[llvm-branch-commits] [clang] [clang-tools-extra] [flang] [lld] [llvm] [ADT] Adopt SmallVectorWithFlags in padding-saving records (PR #233622)
Mehdi Amini via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Oct 19 16:08:44 PDT 2026
https://github.com/joker-eph created https://github.com/llvm/llvm-project/pull/233622
Pack boolean and small-bitfield state into SmallVectorWithFlags across 464 records in LLVM, Clang, MLIR, Flang, LLD, LLDB, BOLT, Polly, and clang-tools-extra. Preserve inline capacities, initial flag values, payload-only comparisons, and existing copy and move behavior. Remove redundant state where doing so provides the same layout improvement.
Add ordinary-vector construction and payload move assignment support. Use ArrayRef for read-only vector interfaces and explicit payload transfers where existing mutable SmallVectorImpl interfaces need ordinary vectors. Add regression tests for flag retention during vector growth, copy, move, serialization, and calling-convention lowering.
Assisted-by: Codex
>From 58fb3700094aa94e6fc0d84754402379d4c27dda Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Mon, 19 Oct 2026 15:40:16 -0700
Subject: [PATCH] [ADT] Adopt SmallVectorWithFlags in padding-saving records
Pack boolean and small-bitfield state into SmallVectorWithFlags across
464 records in LLVM, Clang, MLIR, Flang, LLD, LLDB, BOLT, Polly, and
clang-tools-extra. Preserve inline capacities, initial flag values,
payload-only comparisons, and existing copy and move behavior. Remove
redundant state where doing so provides the same layout improvement.
Add ordinary-vector construction and payload move assignment support.
Use ArrayRef for read-only vector interfaces and explicit payload transfers
where existing mutable SmallVectorImpl interfaces need ordinary vectors.
Add regression tests for flag retention during vector growth, copy, move,
serialization, and calling-convention lowering.
Leave ELFObjectFile lazy caches separate from immutable flags to preserve
independent const access. Leave generated AffineVectorizeOptions unchanged
because its public aggregate contract needs a separate generator change.
Validation: Clang unit tests, check-lld, 21 selected unit-test binaries,
all-target syntax and layout checks, and focused LLVM, Clang, MLIR, Flang,
and BOLT lit tests. The final calling-convention checks passed 336 tests.
Assisted-by: Codex
---
bolt/include/bolt/Core/BinaryFunction.h | 136 +++---
bolt/include/bolt/Core/DebugData.h | 10 +-
bolt/include/bolt/Core/DebugNames.h | 11 +-
bolt/include/bolt/Profile/DataAggregator.h | 23 +-
bolt/lib/Core/BinaryFunction.cpp | 4 +-
bolt/lib/Core/DebugData.cpp | 7 +-
bolt/lib/Core/DebugNames.cpp | 18 +-
bolt/lib/Profile/DataAggregator.cpp | 26 +-
bolt/lib/Profile/DataReader.cpp | 2 +-
bolt/lib/Rewrite/RewriteInstance.cpp | 2 +-
bolt/unittests/Core/BinaryContext.cpp | 20 +
clang-tools-extra/clang-move/Move.cpp | 4 +-
clang-tools-extra/clang-move/Move.h | 9 +-
.../clang-move/tool/ClangMove.cpp | 6 +-
.../clang-tidy/boost/UseRangesCheck.cpp | 13 +-
.../bugprone/AssertSideEffectCheck.cpp | 19 +-
.../bugprone/AssertSideEffectCheck.h | 11 +-
.../clang-tidy/modernize/AvoidBindCheck.cpp | 12 +-
.../clang-tidy/modernize/LoopConvertCheck.cpp | 14 +-
.../clang-tidy/modernize/LoopConvertCheck.h | 7 +-
.../clang-tidy/modernize/LoopConvertUtils.cpp | 22 +-
.../clang-tidy/modernize/LoopConvertUtils.h | 30 +-
.../clang-tidy/modernize/UseNullptrCheck.cpp | 13 +-
.../clang-tidy/modernize/UseNullptrCheck.h | 11 +-
.../readability/MagicNumbersCheck.cpp | 54 ++-
.../readability/MagicNumbersCheck.h | 33 +-
.../readability/NamespaceCommentCheck.cpp | 12 +-
.../readability/NamespaceCommentCheck.h | 5 +-
.../clangd/SystemIncludeExtractor.cpp | 42 +-
.../modularize/ModularizeUtilities.cpp | 2 +-
.../modularize/PreprocessorTracker.cpp | 29 +-
.../unittests/clang-move/ClangMoveTests.cpp | 4 +-
clang/include/clang/AST/ASTConcept.h | 10 +-
clang/include/clang/AST/ASTContext.h | 23 +-
clang/include/clang/AST/ExprConcepts.h | 2 +-
clang/include/clang/AST/VTTBuilder.h | 10 +-
.../Analysis/Analyses/LifetimeSafety/Facts.h | 13 +-
.../Analyses/LifetimeSafety/FactsGenerator.h | 11 +-
clang/include/clang/Basic/Attr.td | 4 +-
clang/include/clang/Basic/Module.h | 142 ++++--
clang/include/clang/Basic/OpenMPKinds.h | 15 +-
clang/include/clang/Basic/Sarif.h | 6 +-
clang/include/clang/Basic/SourceManager.h | 31 +-
clang/include/clang/CodeGen/CodeGenAction.h | 6 +-
.../clang/CodeGen/ConstantInitBuilder.h | 23 +-
.../include/clang/CodeGen/SwiftCallingConv.h | 8 +-
.../DependencyScanning/DependencyGraph.h | 15 +-
clang/include/clang/Driver/Action.h | 22 +-
clang/include/clang/Driver/Driver.h | 13 +-
clang/include/clang/Driver/OffloadBundler.h | 34 +-
.../clang/Driver/RocmInstallationDetector.h | 14 +-
clang/include/clang/Driver/ToolChain.h | 6 +-
clang/include/clang/Edit/Commit.h | 8 +-
.../Serialization/SymbolGraphSerializer.h | 23 +-
clang/include/clang/Frontend/ASTUnit.h | 29 +-
clang/include/clang/Lex/Lexer.h | 4 +-
clang/include/clang/Lex/ModuleMap.h | 16 +-
clang/include/clang/Lex/ModuleMapFile.h | 11 +-
clang/include/clang/Lex/Preprocessor.h | 159 +++++--
clang/include/clang/Lex/PreprocessorLexer.h | 24 +-
clang/include/clang/Parse/Parser.h | 67 ++-
.../clang/Parse/RAIIObjectsForParser.h | 14 +-
clang/include/clang/Sema/DeclSpec.h | 27 +-
clang/include/clang/Sema/ScopeInfo.h | 37 +-
clang/include/clang/Sema/Sema.h | 231 +++++++---
clang/include/clang/Sema/SemaHLSL.h | 10 +-
clang/include/clang/Sema/SemaInternal.h | 22 +-
clang/include/clang/Sema/Template.h | 50 ++-
clang/include/clang/Sema/TemplateDeduction.h | 14 +-
clang/include/clang/Serialization/ASTReader.h | 78 +++-
clang/include/clang/Serialization/ASTWriter.h | 51 ++-
.../include/clang/Serialization/ModuleFile.h | 19 +-
.../Serialization/PCHContainerOperations.h | 6 +-
.../Core/BugReporter/BugReporter.h | 10 +-
.../StaticAnalyzer/Core/CheckerManager.h | 8 +-
.../clang/Tooling/Inclusions/HeaderIncludes.h | 6 +-
.../clang/Tooling/Refactoring/ASTSelection.h | 15 +-
clang/lib/APINotes/APINotesManager.cpp | 14 +-
clang/lib/AST/ASTConcept.cpp | 4 +-
clang/lib/AST/ASTContext.cpp | 8 +-
clang/lib/AST/ASTImporter.cpp | 6 +-
clang/lib/AST/AttrImpl.cpp | 2 +-
clang/lib/AST/Availability.cpp | 36 +-
clang/lib/AST/ByteCode/Disasm.cpp | 20 +-
clang/lib/AST/ByteCode/Interp.h | 4 +-
clang/lib/AST/ByteCode/InterpState.cpp | 13 +-
clang/lib/AST/ByteCode/InterpState.h | 13 +-
clang/lib/AST/CommentParser.cpp | 16 +-
clang/lib/AST/ExprConstant.cpp | 34 +-
clang/lib/AST/MicrosoftMangle.cpp | 45 +-
clang/lib/AST/OpenMPClause.cpp | 8 +-
clang/lib/AST/RecordLayoutBuilder.cpp | 77 ++--
clang/lib/AST/VTTBuilder.cpp | 10 +-
clang/lib/AST/VTableBuilder.cpp | 34 +-
clang/lib/Analysis/CFG.cpp | 26 +-
clang/lib/Analysis/CalledOnceCheck.cpp | 41 +-
.../LifetimeSafety/FactsGenerator.cpp | 9 +-
clang/lib/Basic/Module.cpp | 68 +--
clang/lib/Basic/Sarif.cpp | 13 +-
clang/lib/Basic/SourceManager.cpp | 14 +-
clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 8 +-
clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 12 +-
clang/lib/CIR/CodeGen/CIRGenFunction.h | 35 +-
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 12 +-
clang/lib/CIR/CodeGen/CIRGenModule.h | 8 +-
.../CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 74 ++--
clang/lib/CIR/CodeGen/CIRGenVTables.cpp | 2 +-
.../Transforms/CallConvLoweringPass.cpp | 4 +-
clang/lib/CodeGen/BackendConsumer.h | 6 +-
clang/lib/CodeGen/CGBuiltin.cpp | 6 +-
clang/lib/CodeGen/CGCUDANV.cpp | 36 +-
clang/lib/CodeGen/CGCall.cpp | 6 +-
clang/lib/CodeGen/CGClass.cpp | 18 +-
clang/lib/CodeGen/CGCleanup.h | 10 +-
clang/lib/CodeGen/CGCoroutine.cpp | 2 +-
clang/lib/CodeGen/CGDebugInfo.cpp | 8 +-
clang/lib/CodeGen/CGDecl.cpp | 14 +-
clang/lib/CodeGen/CGDeclCXX.cpp | 4 +-
clang/lib/CodeGen/CGException.cpp | 4 +-
clang/lib/CodeGen/CGExpr.cpp | 12 +-
clang/lib/CodeGen/CGExprConstant.cpp | 22 +-
clang/lib/CodeGen/CGExprScalar.cpp | 2 +-
clang/lib/CodeGen/CGObjC.cpp | 8 +-
clang/lib/CodeGen/CGObjCMac.cpp | 25 +-
clang/lib/CodeGen/CGOpenMPRuntime.cpp | 56 +--
clang/lib/CodeGen/CGOpenMPRuntime.h | 75 +++-
clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp | 2 +-
clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 67 +--
clang/lib/CodeGen/CGStmt.cpp | 27 +-
clang/lib/CodeGen/CGStmtOpenMP.cpp | 58 +--
clang/lib/CodeGen/CGVTables.cpp | 4 +-
clang/lib/CodeGen/CodeGenAction.cpp | 62 ++-
clang/lib/CodeGen/CodeGenFunction.cpp | 31 +-
clang/lib/CodeGen/CodeGenFunction.h | 70 ++-
clang/lib/CodeGen/CodeGenModule.cpp | 24 +-
clang/lib/CodeGen/CodeGenModule.h | 15 +-
clang/lib/CodeGen/CodeGenPGO.cpp | 54 +--
clang/lib/CodeGen/ConstantEmitter.h | 14 +-
clang/lib/CodeGen/ConstantInitBuilder.cpp | 2 +-
clang/lib/CodeGen/ItaniumCXXABI.cpp | 57 +--
clang/lib/CodeGen/MicrosoftCXXABI.cpp | 4 +-
.../CodeGen/ObjectFilePCHContainerWriter.cpp | 4 +-
clang/lib/CodeGen/SwiftCallingConv.cpp | 14 +-
clang/lib/CodeGen/TargetBuiltins/ARM.cpp | 6 +-
clang/lib/CodeGen/Targets/Sparc.cpp | 19 +-
clang/lib/CodeGen/VarBypassDetector.cpp | 6 +-
clang/lib/CodeGen/VarBypassDetector.h | 9 +-
.../DependencyScanning/ModuleDepCollector.cpp | 38 +-
clang/lib/Driver/Compilation.cpp | 12 +-
clang/lib/Driver/CreateASTUnitFromArgs.cpp | 4 +-
clang/lib/Driver/Driver.cpp | 36 +-
clang/lib/Driver/OffloadBundler.cpp | 40 +-
clang/lib/Driver/ToolChain.cpp | 7 +-
clang/lib/Driver/ToolChains/AMDGPU.cpp | 16 +-
clang/lib/Driver/ToolChains/Hexagon.cpp | 6 +-
clang/lib/Driver/ToolChains/Hexagon.h | 5 +-
clang/lib/Edit/Commit.cpp | 20 +-
.../Serialization/SymbolGraphSerializer.cpp | 15 +-
clang/lib/Format/AffectedRangeManager.cpp | 8 +-
clang/lib/Format/AffectedRangeManager.h | 4 +-
clang/lib/Format/ContinuationIndenter.cpp | 22 +-
clang/lib/Format/ContinuationIndenter.h | 32 +-
clang/lib/Format/Format.cpp | 50 ++-
clang/lib/Format/FormatToken.cpp | 4 +-
clang/lib/Format/FormatToken.h | 14 +-
clang/lib/Format/FormatTokenLexer.cpp | 32 +-
clang/lib/Format/FormatTokenLexer.h | 12 +-
clang/lib/Format/MacroCallReconstructor.cpp | 8 +-
clang/lib/Format/QualifierAlignmentFixer.cpp | 8 +-
clang/lib/Format/QualifierAlignmentFixer.h | 8 +-
clang/lib/Format/SortJavaScriptImports.cpp | 60 +--
clang/lib/Format/TokenAnnotator.cpp | 86 ++--
clang/lib/Format/TokenAnnotator.h | 36 +-
clang/lib/Format/UnwrappedLineFormatter.cpp | 11 +-
clang/lib/Format/UnwrappedLineParser.cpp | 72 ++--
clang/lib/Format/UnwrappedLineParser.h | 22 +-
clang/lib/Format/WhitespaceManager.cpp | 8 +-
clang/lib/Format/WhitespaceManager.h | 11 +-
clang/lib/Frontend/ASTUnit.cpp | 20 +-
clang/lib/Frontend/ChainedIncludesSource.cpp | 2 +-
clang/lib/Frontend/CompilerInstance.cpp | 15 +-
clang/lib/Frontend/FrontendAction.cpp | 19 +-
clang/lib/Frontend/HeaderIncludeGen.cpp | 11 +-
clang/lib/Frontend/PrecompiledPreamble.cpp | 2 +-
.../Frontend/SerializedDiagnosticPrinter.cpp | 19 +-
clang/lib/Index/IndexTypeSourceInfo.cpp | 21 +-
clang/lib/Lex/DependencyDirectivesScanner.cpp | 16 +-
clang/lib/Lex/HeaderSearch.cpp | 5 +-
clang/lib/Lex/Lexer.cpp | 91 ++--
clang/lib/Lex/MacroArgs.cpp | 10 +-
clang/lib/Lex/ModuleMap.cpp | 128 +++---
clang/lib/Lex/ModuleMapFile.cpp | 21 +-
clang/lib/Lex/PPDirectives.cpp | 97 +++--
clang/lib/Lex/PPExpressions.cpp | 10 +-
clang/lib/Lex/PPLexerChange.cpp | 10 +-
clang/lib/Lex/PPMacroExpansion.cpp | 2 +-
clang/lib/Lex/Pragma.cpp | 42 +-
clang/lib/Lex/Preprocessor.cpp | 64 +--
clang/lib/Lex/PreprocessorLexer.cpp | 8 +-
clang/lib/Parse/ParseCXXInlineMethods.cpp | 8 +-
clang/lib/Parse/ParseDecl.cpp | 11 +-
clang/lib/Parse/ParseDeclCXX.cpp | 23 +-
clang/lib/Parse/ParseExpr.cpp | 13 +-
clang/lib/Parse/ParseExprCXX.cpp | 17 +-
clang/lib/Parse/ParseObjc.cpp | 11 +-
clang/lib/Parse/ParseOpenACC.cpp | 19 +-
clang/lib/Parse/ParseOpenMP.cpp | 10 +-
clang/lib/Parse/ParseStmt.cpp | 6 +-
clang/lib/Parse/ParseTemplate.cpp | 4 +-
clang/lib/Parse/ParseTentative.cpp | 2 +-
clang/lib/Parse/Parser.cpp | 11 +-
clang/lib/Sema/CoroutineStmtBuilder.h | 10 +-
clang/lib/Sema/JumpDiagnostics.cpp | 11 +-
clang/lib/Sema/ScopeInfo.cpp | 2 +-
clang/lib/Sema/Sema.cpp | 28 +-
clang/lib/Sema/SemaAccess.cpp | 44 +-
clang/lib/Sema/SemaAttr.cpp | 12 +-
clang/lib/Sema/SemaAvailability.cpp | 2 +-
clang/lib/Sema/SemaBase.cpp | 4 +-
clang/lib/Sema/SemaCUDA.cpp | 4 +-
clang/lib/Sema/SemaChecking.cpp | 16 +-
clang/lib/Sema/SemaConcept.cpp | 83 ++--
clang/lib/Sema/SemaCoroutine.cpp | 41 +-
clang/lib/Sema/SemaDecl.cpp | 21 +-
clang/lib/Sema/SemaDeclCXX.cpp | 35 +-
clang/lib/Sema/SemaExpr.cpp | 117 +++--
clang/lib/Sema/SemaExprCXX.cpp | 60 +--
clang/lib/Sema/SemaHLSL.cpp | 42 +-
clang/lib/Sema/SemaLambda.cpp | 38 +-
clang/lib/Sema/SemaLifetimeSafety.h | 10 +-
clang/lib/Sema/SemaLookup.cpp | 14 +-
clang/lib/Sema/SemaModule.cpp | 8 +-
clang/lib/Sema/SemaOpenMP.cpp | 107 +++--
clang/lib/Sema/SemaOverload.cpp | 92 ++--
clang/lib/Sema/SemaPseudoObject.cpp | 12 +-
clang/lib/Sema/SemaSYCL.cpp | 10 +-
clang/lib/Sema/SemaStmt.cpp | 12 +-
clang/lib/Sema/SemaTemplate.cpp | 102 +++--
clang/lib/Sema/SemaTemplateDeduction.cpp | 114 +++--
clang/lib/Sema/SemaTemplateInstantiate.cpp | 16 +-
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 48 ++-
clang/lib/Sema/SemaTemplateVariadic.cpp | 2 +-
clang/lib/Sema/SemaType.cpp | 41 +-
clang/lib/Sema/TreeTransform.h | 62 +--
clang/lib/Serialization/ASTReader.cpp | 117 ++---
clang/lib/Serialization/ASTReaderDecl.cpp | 13 +-
clang/lib/Serialization/ASTReaderStmt.cpp | 6 +-
clang/lib/Serialization/ASTWriter.cpp | 176 ++++----
clang/lib/Serialization/ASTWriterDecl.cpp | 2 +-
clang/lib/Serialization/GeneratePCH.cpp | 12 +-
.../Serialization/PCHContainerOperations.cpp | 6 +-
.../Checkers/CallAndMessageChecker.cpp | 31 +-
.../Checkers/LocalizationChecker.cpp | 32 +-
.../Checkers/StackAddrEscapeChecker.cpp | 11 +-
.../lib/Tooling/Inclusions/HeaderIncludes.cpp | 19 +-
.../ClangOffloadBundler.cpp | 20 +-
clang/tools/clang-scan-deps/ClangScanDeps.cpp | 11 +-
clang/tools/driver/cc1as_main.cpp | 22 +-
clang/tools/driver/driver.cpp | 4 +-
clang/tools/libclang/CIndex.cpp | 38 +-
clang/tools/libclang/CursorVisitor.h | 26 +-
clang/tools/libclang/Indexing.cpp | 14 +-
clang/utils/TableGen/ClangAttrEmitter.cpp | 12 +-
clang/utils/TableGen/HLSLEmitter.cpp | 38 +-
clang/utils/TableGen/NeonEmitter.cpp | 48 ++-
clang/utils/TableGen/SveEmitter.cpp | 12 +-
flang/include/flang/Lower/CallInterface.h | 7 +-
flang/include/flang/Lower/PFTBuilder.h | 48 ++-
.../flang/Optimizer/Analysis/AliasAnalysis.h | 48 ++-
.../Optimizer/Builder/TemporaryStorage.h | 11 +-
flang/lib/Lower/Bridge.cpp | 95 ++--
flang/lib/Lower/CallInterface.cpp | 4 +-
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 26 +-
.../lib/Lower/OpenMP/DataSharingProcessor.cpp | 25 +-
flang/lib/Lower/OpenMP/DataSharingProcessor.h | 36 +-
flang/lib/Lower/OpenMP/OpenMP.cpp | 62 ++-
flang/lib/Lower/PFTBuilder.cpp | 66 +--
.../Lower/Support/PrivateReductionUtils.cpp | 64 +--
.../lib/Optimizer/Analysis/AliasAnalysis.cpp | 69 +--
.../Optimizer/Builder/TemporaryStorage.cpp | 13 +-
.../LowerHLFIROrderedAssignments.cpp | 16 +-
.../Transforms/ScheduleOrderedAssignments.cpp | 51 ++-
.../lib/Optimizer/Transforms/FIRToMemRef.cpp | 18 +-
.../Optimizer/AliasAnalysisCacheTest.cpp | 19 +
lld/COFF/Chunks.cpp | 4 +-
lld/COFF/Config.h | 83 +++-
lld/COFF/DebugTypes.cpp | 2 +-
lld/COFF/Driver.cpp | 94 ++--
lld/COFF/DriverUtils.cpp | 4 +-
lld/COFF/InputFiles.cpp | 4 +-
lld/COFF/LTO.cpp | 14 +-
lld/COFF/MapFile.cpp | 2 +-
lld/COFF/SymbolTable.cpp | 2 +-
lld/COFF/Symbols.cpp | 2 +-
lld/COFF/Writer.cpp | 6 +-
lld/ELF/Arch/AArch64.cpp | 18 +-
lld/ELF/Arch/ARM.cpp | 11 +-
lld/ELF/Arch/LoongArch.cpp | 44 +-
lld/ELF/Arch/Mips.cpp | 30 +-
lld/ELF/Arch/MipsArchTree.cpp | 4 +-
lld/ELF/Arch/PPC.cpp | 16 +-
lld/ELF/Arch/PPC64.cpp | 34 +-
lld/ELF/Arch/RISCV.cpp | 38 +-
lld/ELF/Arch/SPARCV9.cpp | 2 +-
lld/ELF/Arch/SystemZ.cpp | 6 +-
lld/ELF/Arch/X86.cpp | 16 +-
lld/ELF/Arch/X86_64.cpp | 26 +-
lld/ELF/Config.h | 385 ++++++++++++-----
lld/ELF/DWARF.cpp | 2 +-
lld/ELF/Driver.cpp | 404 +++++++++---------
lld/ELF/ICF.cpp | 6 +-
lld/ELF/InputFiles.cpp | 57 +--
lld/ELF/InputFiles.h | 25 +-
lld/ELF/InputSection.cpp | 35 +-
lld/ELF/LTO.cpp | 36 +-
lld/ELF/LinkerScript.cpp | 70 +--
lld/ELF/LinkerScript.h | 33 +-
lld/ELF/MapFile.cpp | 8 +-
lld/ELF/MarkLive.cpp | 9 +-
lld/ELF/OutputSections.cpp | 56 +--
lld/ELF/OutputSections.h | 68 ++-
lld/ELF/RelocScan.h | 14 +-
lld/ELF/Relocations.cpp | 44 +-
lld/ELF/ScriptParser.cpp | 48 ++-
lld/ELF/SymbolTable.cpp | 4 +-
lld/ELF/Symbols.cpp | 15 +-
lld/ELF/SyntheticSections.cpp | 172 ++++----
lld/ELF/SyntheticSections.h | 35 +-
lld/ELF/Target.cpp | 4 +-
lld/ELF/Thunks.cpp | 32 +-
lld/ELF/Writer.cpp | 154 +++----
lld/MachO/Config.h | 110 +++--
lld/MachO/Driver.cpp | 154 ++++---
lld/MachO/DriverUtils.cpp | 2 +-
lld/MachO/InputFiles.cpp | 28 +-
lld/MachO/InputFiles.h | 30 +-
lld/MachO/InputSection.cpp | 2 +-
lld/MachO/LTO.cpp | 6 +-
lld/MachO/SectionPriorities.cpp | 18 +-
lld/MachO/Symbols.h | 2 +-
lld/MachO/SyntheticSections.cpp | 8 +-
lld/MachO/Writer.cpp | 18 +-
lld/wasm/Config.h | 62 ++-
lld/wasm/Driver.cpp | 79 ++--
lld/wasm/InputChunks.cpp | 8 +-
lld/wasm/InputChunks.h | 5 +-
lld/wasm/InputElement.h | 2 +-
lld/wasm/InputFiles.cpp | 2 +-
lld/wasm/InputFiles.h | 2 +-
lld/wasm/LTO.cpp | 4 +-
lld/wasm/MarkLive.cpp | 4 +-
lld/wasm/OutputSections.cpp | 6 +-
lld/wasm/OutputSegment.h | 2 +-
lld/wasm/Relocations.cpp | 4 +-
lld/wasm/SymbolTable.cpp | 12 +-
lld/wasm/Symbols.cpp | 2 +-
lld/wasm/Symbols.h | 8 +-
lld/wasm/SyntheticSections.cpp | 16 +-
lld/wasm/SyntheticSections.h | 2 +-
lld/wasm/Writer.cpp | 63 +--
lldb/include/lldb/Core/FormatEntity.h | 25 +-
lldb/source/Core/Disassembler.cpp | 2 +-
lldb/source/Core/FormatEntity.cpp | 16 +-
.../Clang/ClangASTImporter.cpp | 4 +-
.../MacOSX/PlatformAppleSimulator.cpp | 4 +-
.../Platform/MacOSX/PlatformAppleSimulator.h | 10 +-
.../DWARF/SymbolFileDWARFDebugMap.cpp | 4 +-
.../DWARF/SymbolFileDWARFDebugMap.h | 10 +-
llvm/include/llvm/ADT/GenericUniformityImpl.h | 14 +-
llvm/include/llvm/ADT/SmallVectorWithFlags.h | 61 +++
llvm/include/llvm/Analysis/AliasAnalysis.h | 26 +-
llvm/include/llvm/Analysis/AssumptionCache.h | 12 +-
.../llvm/Analysis/BasicAliasAnalysis.h | 2 +-
.../llvm/Analysis/BlockFrequencyInfoImpl.h | 38 +-
.../llvm/Analysis/GenericDomTreeUpdater.h | 7 +-
.../llvm/Analysis/GenericDomTreeUpdaterImpl.h | 8 +-
.../llvm/Analysis/LoopAccessAnalysis.h | 33 +-
.../include/llvm/Analysis/LoopCacheAnalysis.h | 8 +-
llvm/include/llvm/Analysis/PtrUseVisitor.h | 15 +-
llvm/include/llvm/Analysis/ScalarEvolution.h | 13 +-
.../llvm/Analysis/TargetTransformInfo.h | 18 +-
.../ImportedFunctionsInliningStatistics.h | 9 +-
llvm/include/llvm/AsmParser/LLParser.h | 18 +-
llvm/include/llvm/Bitstream/BitstreamWriter.h | 8 +
llvm/include/llvm/CGData/StableFunctionMap.h | 14 +-
.../llvm/CGData/StableFunctionMapRecord.h | 2 +-
llvm/include/llvm/CodeGen/AsmPrinter.h | 38 +-
llvm/include/llvm/CodeGen/CallingConvLower.h | 57 +--
.../llvm/CodeGen/GlobalISel/CallLowering.h | 9 +-
.../llvm/CodeGen/GlobalISel/GISelWorkList.h | 18 +-
llvm/include/llvm/CodeGen/LexicalScopes.h | 14 +-
llvm/include/llvm/CodeGen/LiveIntervalUnion.h | 24 +-
llvm/include/llvm/CodeGen/MachineBasicBlock.h | 29 +-
llvm/include/llvm/CodeGen/MachineFrameInfo.h | 17 +-
llvm/include/llvm/CodeGen/MachineFunction.h | 39 +-
llvm/include/llvm/CodeGen/MachinePipeliner.h | 5 +-
.../llvm/CodeGen/MachineRegisterInfo.h | 12 +-
llvm/include/llvm/CodeGen/MachineScheduler.h | 20 +-
llvm/include/llvm/CodeGen/Rematerializer.h | 6 +-
llvm/include/llvm/CodeGen/ScheduleDAG.h | 8 +-
llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h | 22 +-
llvm/include/llvm/CodeGen/SelectionDAG.h | 19 +
.../llvm/CodeGen/SwitchLoweringUtils.h | 19 +-
llvm/include/llvm/CodeGen/TargetLowering.h | 122 +++---
llvm/include/llvm/CodeGen/TargetSchedule.h | 9 +-
llvm/include/llvm/DTLTO/DTLTO.h | 22 +-
.../llvm/DWARFLinker/Classic/DWARFLinker.h | 23 +-
llvm/include/llvm/DebugInfo/DIContext.h | 10 +-
.../llvm/DebugInfo/DWARF/DWARFDebugMacro.h | 6 +-
.../DWARF/LowLevel/DWARFExpression.h | 19 +-
.../llvm/ExecutionEngine/ExecutionEngine.h | 57 ++-
.../Orc/TargetProcess/LibraryScanner.h | 9 +-
.../llvm/Frontend/OpenMP/OMPIRBuilder.h | 38 +-
llvm/include/llvm/IR/DIBuilder.h | 5 +-
llvm/include/llvm/IR/DataLayout.h | 13 +-
llvm/include/llvm/IR/DroppedVariableStats.h | 15 +-
llvm/include/llvm/IR/LegacyPassManagers.h | 4 +-
llvm/include/llvm/IR/PassTimingInfo.h | 9 +-
llvm/include/llvm/LTO/LTO.h | 33 +-
llvm/include/llvm/MC/DXContainerInfo.h | 13 +-
llvm/include/llvm/MC/DXContainerPSVInfo.h | 17 +-
llvm/include/llvm/MC/MCAssembler.h | 21 +-
llvm/include/llvm/MC/MCCodeView.h | 6 +-
llvm/include/llvm/MC/MCContext.h | 20 +-
llvm/include/llvm/MC/MCDwarf.h | 38 +-
llvm/include/llvm/MC/MCELFStreamer.h | 18 +-
llvm/include/llvm/MC/MCInstPrinter.h | 15 +-
llvm/include/llvm/MC/MCObjectStreamer.h | 17 +-
llvm/include/llvm/MC/MCObjectWriter.h | 14 +-
llvm/include/llvm/MC/MCParser/AsmLexer.h | 7 +-
llvm/include/llvm/MC/MCParser/MCAsmParser.h | 22 +-
llvm/include/llvm/MCA/Instruction.h | 18 +-
llvm/include/llvm/ObjCopy/CommonConfig.h | 67 ++-
llvm/include/llvm/ObjCopy/ELF/ELFConfig.h | 15 +-
llvm/include/llvm/Object/MachO.h | 12 +-
llvm/include/llvm/Object/OffloadBundle.h | 16 +-
.../include/llvm/ObjectYAML/DXContainerYAML.h | 16 +-
llvm/include/llvm/Option/OptTable.h | 14 +-
llvm/include/llvm/PassAnalysisSupport.h | 14 +-
.../include/llvm/ProfileData/DataAccessProf.h | 10 +-
llvm/include/llvm/ProfileData/GCOV.h | 8 +-
.../llvm/ProfileData/InstrProfWriter.h | 33 +-
llvm/include/llvm/ProfileData/MemProfReader.h | 14 +-
.../llvm/ProfileData/SampleProfWriter.h | 28 +-
llvm/include/llvm/SandboxIR/Tracker.h | 17 +-
llvm/include/llvm/Support/CFGDiff.h | 11 +-
llvm/include/llvm/Support/CFGUpdate.h | 5 +-
llvm/include/llvm/Support/DebugCounter.h | 27 +-
llvm/include/llvm/Support/GenericDomTree.h | 27 +-
.../llvm/Support/GenericDomTreeConstruction.h | 13 +-
llvm/include/llvm/Support/GlobPattern.h | 12 +-
llvm/include/llvm/Support/LSP/Transport.h | 16 +-
llvm/include/llvm/Support/SuffixTree.h | 15 +-
llvm/include/llvm/Support/YAMLTraits.h | 13 +
llvm/include/llvm/Transforms/IPO/Attributor.h | 21 +-
.../llvm/Transforms/IPO/Instrumentor.h | 9 +-
.../llvm/Transforms/Scalar/ConstantHoisting.h | 6 +-
llvm/include/llvm/Transforms/Utils/Cloning.h | 11 +-
.../llvm/Transforms/Utils/CodeExtractor.h | 25 +-
.../Utils/LockstepReverseIterator.h | 29 +-
.../include/llvm/Transforms/Utils/LoopUtils.h | 9 +-
.../Transforms/Utils/MemoryTaggingSupport.h | 8 +-
.../Utils/ScalarEvolutionExpander.h | 32 +-
.../Vectorize/LoopVectorizationLegality.h | 28 +-
llvm/lib/Analysis/AssumptionCache.cpp | 6 +-
llvm/lib/Analysis/BasicAliasAnalysis.cpp | 15 +-
llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp | 10 +-
.../ImportedFunctionsInliningStatistics.cpp | 21 +-
llvm/lib/Analysis/KernelInfo.cpp | 15 +-
llvm/lib/Analysis/LoopAccessAnalysis.cpp | 44 +-
llvm/lib/Analysis/LoopCacheAnalysis.cpp | 34 +-
llvm/lib/Analysis/MemorySSAUpdater.cpp | 25 +-
llvm/lib/Analysis/PtrUseVisitor.cpp | 6 +-
llvm/lib/Analysis/ScalarEvolution.cpp | 11 +-
llvm/lib/AsmParser/LLParser.cpp | 10 +-
llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 88 ++--
llvm/lib/CAS/OnDiskGraphDB.cpp | 14 +-
llvm/lib/CGData/StableFunctionMap.cpp | 6 +-
llvm/lib/CGData/StableFunctionMapRecord.cpp | 6 +-
llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp | 13 +-
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 22 +-
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 7 +-
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h | 2 +-
.../CodeGen/AsmPrinter/DebugHandlerBase.cpp | 2 +-
llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h | 29 +-
llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h | 12 +-
.../CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 2 +-
.../lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 16 +-
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 26 +-
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 52 ++-
.../CodeGen/AsmPrinter/DwarfExpression.cpp | 20 +-
llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h | 6 +-
llvm/lib/CodeGen/CallingConvLower.cpp | 44 +-
.../lib/CodeGen/ComplexDeinterleavingPass.cpp | 16 +-
llvm/lib/CodeGen/DFAPacketizer.cpp | 2 +-
.../CodeGen/FixupStatepointCallerSaved.cpp | 18 +-
llvm/lib/CodeGen/GlobalISel/CallLowering.cpp | 4 +-
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 49 ++-
llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp | 31 +-
llvm/lib/CodeGen/LexicalScopes.cpp | 4 +-
.../LiveDebugValues/InstrRefBasedImpl.cpp | 23 +-
.../LiveDebugValues/InstrRefBasedImpl.h | 8 +-
llvm/lib/CodeGen/LiveIntervalUnion.cpp | 13 +-
llvm/lib/CodeGen/MachineCopyPropagation.cpp | 23 +-
llvm/lib/CodeGen/MachineFunction.cpp | 4 +-
llvm/lib/CodeGen/MachineLICM.cpp | 53 ++-
llvm/lib/CodeGen/MachineOutliner.cpp | 14 +-
llvm/lib/CodeGen/MachinePipeliner.cpp | 33 +-
llvm/lib/CodeGen/MachineRegisterInfo.cpp | 19 +-
llvm/lib/CodeGen/MachineScheduler.cpp | 45 +-
llvm/lib/CodeGen/MachineVerifier.cpp | 30 +-
llvm/lib/CodeGen/PrologEpilogInserter.cpp | 29 +-
llvm/lib/CodeGen/RegAllocFast.cpp | 32 +-
llvm/lib/CodeGen/RegAllocGreedy.cpp | 10 +-
llvm/lib/CodeGen/RegAllocGreedy.h | 15 +-
llvm/lib/CodeGen/RegisterCoalescer.cpp | 28 +-
llvm/lib/CodeGen/Rematerializer.cpp | 10 +-
llvm/lib/CodeGen/ScheduleDAG.cpp | 8 +-
llvm/lib/CodeGen/ScheduleDAGInstrs.cpp | 19 +-
.../SelectionDAG/ScheduleDAGRRList.cpp | 18 +-
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 10 +-
.../SelectionDAG/SelectionDAGBuilder.cpp | 101 +++--
.../SelectionDAG/SelectionDAGBuilder.h | 25 +-
.../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 27 +-
.../SelectionDAG/StatepointLowering.cpp | 2 +-
llvm/lib/CodeGen/TargetSchedule.cpp | 8 +-
llvm/lib/DTLTO/DTLTO.cpp | 12 +-
llvm/lib/DTLTO/DTLTOInputFiles.cpp | 2 +-
llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 47 +-
.../Parallel/DIEAttributeCloner.cpp | 14 +-
.../Parallel/DWARFLinkerCompileUnit.cpp | 25 +-
.../Parallel/DWARFLinkerCompileUnit.h | 9 +-
.../Parallel/DWARFLinkerGlobalData.h | 18 +-
.../DWARFLinker/Parallel/DWARFLinkerImpl.cpp | 38 +-
.../DWARFLinker/Parallel/DWARFLinkerImpl.h | 18 +-
.../Parallel/DependencyTracker.cpp | 8 +-
.../DWARFLinker/Parallel/DependencyTracker.h | 10 +-
.../DebugInfo/CodeView/TypeStreamMerger.cpp | 36 +-
llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp | 6 +-
.../DWARF/DWARFExpressionPrinter.cpp | 12 +-
llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 4 +-
llvm/lib/ExecutionEngine/ExecutionEngine.cpp | 12 +-
.../Orc/TargetProcess/LibraryScanner.cpp | 4 +-
llvm/lib/ExecutionEngine/TargetSelect.cpp | 7 +-
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp | 12 +-
llvm/lib/IR/AsmWriter.cpp | 43 +-
llvm/lib/IR/DIBuilder.cpp | 10 +-
llvm/lib/IR/DataLayout.cpp | 10 +-
llvm/lib/IR/DroppedVariableStats.cpp | 7 +-
llvm/lib/IR/DroppedVariableStatsIR.cpp | 2 +-
llvm/lib/IR/LLVMContext.cpp | 18 +-
llvm/lib/IR/LLVMContextImpl.h | 17 +-
llvm/lib/IR/LegacyPassManager.cpp | 2 +-
llvm/lib/IR/PassTimingInfo.cpp | 9 +-
llvm/lib/IR/Verifier.cpp | 25 +-
llvm/lib/LTO/LTO.cpp | 14 +-
llvm/lib/MC/DXContainerInfo.cpp | 10 +-
llvm/lib/MC/DXContainerPSVInfo.cpp | 2 +-
llvm/lib/MC/MCAssembler.cpp | 16 +-
llvm/lib/MC/MCCodeView.cpp | 4 +-
llvm/lib/MC/MCContext.cpp | 16 +-
llvm/lib/MC/MCDwarf.cpp | 19 +-
llvm/lib/MC/MCELFStreamer.cpp | 24 +-
llvm/lib/MC/MCObjectStreamer.cpp | 22 +-
llvm/lib/MC/MCObjectWriter.cpp | 3 +-
llvm/lib/MC/MCParser/AsmLexer.cpp | 2 +-
llvm/lib/MC/MCParser/AsmParser.cpp | 25 +-
llvm/lib/MC/MCParser/MasmParser.cpp | 12 +-
llvm/lib/MC/MachObjectWriter.cpp | 4 +-
llvm/lib/ObjCopy/Archive.cpp | 6 +-
llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp | 15 +-
llvm/lib/ObjCopy/ConfigManager.cpp | 44 +-
llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp | 60 +--
llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp | 14 +-
llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp | 6 +-
llvm/lib/Object/MachOObjectFile.cpp | 29 +-
llvm/lib/ObjectYAML/DXContainerEmitter.cpp | 21 +-
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 4 +-
llvm/lib/Option/OptTable.cpp | 23 +-
.../ProfileData/Coverage/CoverageMapping.cpp | 28 +-
llvm/lib/ProfileData/DataAccessProf.cpp | 2 +-
llvm/lib/ProfileData/GCOV.cpp | 19 +-
llvm/lib/ProfileData/InstrProfWriter.cpp | 46 +-
llvm/lib/ProfileData/MemProfReader.cpp | 8 +-
llvm/lib/ProfileData/SampleProfWriter.cpp | 16 +-
llvm/lib/Support/DebugCounter.cpp | 6 +-
llvm/lib/Support/GlobPattern.cpp | 10 +-
llvm/lib/Support/LSP/Transport.cpp | 14 +-
llvm/lib/Support/SuffixTree.cpp | 2 +-
llvm/lib/Support/YAMLParser.cpp | 118 ++---
llvm/lib/TableGen/TGParser.cpp | 14 +-
llvm/lib/TableGen/TGParser.h | 16 +-
.../Target/AArch64/AArch64ISelLowering.cpp | 74 ++--
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 8 +-
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 14 +-
.../AArch64/AArch64MachineFunctionInfo.cpp | 8 +-
.../AArch64/AArch64MachineFunctionInfo.h | 74 ++--
.../Target/AArch64/AArch64StackTagging.cpp | 4 +-
.../AArch64/AArch64TargetTransformInfo.cpp | 8 +-
.../AArch64/GISel/AArch64CallLowering.cpp | 4 +-
.../MCTargetDesc/AArch64InstPrinter.cpp | 8 +-
.../MCTargetDesc/AArch64TargetStreamer.cpp | 8 +-
llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 10 +-
llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h | 10 +-
llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp | 6 +-
llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp | 44 +-
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 17 +-
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h | 7 +-
llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp | 11 +-
.../AMDGPU/AMDGPUTargetTransformInfo.cpp | 6 +-
llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp | 6 +-
llvm/lib/Target/AMDGPU/GCNSchedStrategy.h | 6 +-
llvm/lib/Target/AMDGPU/R600ISelLowering.cpp | 4 +-
llvm/lib/Target/AMDGPU/R600ISelLowering.h | 3 +-
llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 74 ++--
llvm/lib/Target/AMDGPU/SIISelLowering.h | 27 +-
.../Target/AMDGPU/SIMachineFunctionInfo.cpp | 59 ++-
.../lib/Target/AMDGPU/SIMachineFunctionInfo.h | 191 +++++----
llvm/lib/Target/AMDGPU/SIModeRegister.cpp | 18 +-
llvm/lib/Target/ARC/ARCISelLowering.cpp | 40 +-
llvm/lib/Target/ARC/ARCISelLowering.h | 11 +-
llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 14 +-
llvm/lib/Target/ARM/ARMAsmPrinter.h | 7 +-
llvm/lib/Target/ARM/ARMBasicBlockInfo.cpp | 6 +-
llvm/lib/Target/ARM/ARMBasicBlockInfo.h | 12 +-
llvm/lib/Target/ARM/ARMCallLowering.cpp | 2 +-
llvm/lib/Target/ARM/ARMConstantIslandPass.cpp | 103 +++--
llvm/lib/Target/ARM/ARMHazardRecognizer.cpp | 12 +-
llvm/lib/Target/ARM/ARMHazardRecognizer.h | 6 +-
llvm/lib/Target/ARM/ARMISelLowering.cpp | 107 ++---
llvm/lib/Target/ARM/ARMISelLowering.h | 19 +-
llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 95 ++--
llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp | 29 +-
llvm/lib/Target/ARM/ARMParallelDSP.cpp | 41 +-
.../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 18 +-
.../ARM/MCTargetDesc/ARMELFStreamer.cpp | 49 ++-
.../ARM/MCTargetDesc/ARMInstPrinter.cpp | 2 +-
.../ARM/MCTargetDesc/ARMUnwindOpAsm.cpp | 2 +-
.../Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h | 12 +-
llvm/lib/Target/ARM/Thumb2SizeReduction.cpp | 45 +-
llvm/lib/Target/AVR/AVRISelLowering.cpp | 55 ++-
llvm/lib/Target/AVR/AVRISelLowering.h | 12 +-
llvm/lib/Target/BPF/BPFISelLowering.cpp | 44 +-
llvm/lib/Target/BPF/BPFISelLowering.h | 12 +-
llvm/lib/Target/BPF/BTFDebug.cpp | 9 +-
llvm/lib/Target/BPF/BTFDebug.h | 9 +-
llvm/lib/Target/CSKY/CSKYISelLowering.cpp | 55 +--
llvm/lib/Target/CSKY/CSKYISelLowering.h | 8 +-
.../CSKY/MCTargetDesc/CSKYInstPrinter.cpp | 12 +-
.../Target/Hexagon/HexagonCopyToCombine.cpp | 27 +-
.../Target/Hexagon/HexagonISelDAGToDAG.cpp | 31 +-
.../Target/Hexagon/HexagonISelLowering.cpp | 67 ++-
llvm/lib/Target/Hexagon/HexagonISelLowering.h | 34 +-
llvm/lib/Target/Lanai/LanaiISelLowering.cpp | 45 +-
llvm/lib/Target/Lanai/LanaiISelLowering.h | 22 +-
.../LoongArch/LoongArchISelLowering.cpp | 63 +--
.../Target/LoongArch/LoongArchISelLowering.h | 15 +-
.../LoongArch/LoongArchMachineFunctionInfo.h | 10 +-
.../MCTargetDesc/LoongArchInstPrinter.cpp | 2 +-
.../Target/M68k/GISel/M68kCallLowering.cpp | 2 +-
llvm/lib/Target/M68k/M68kISelLowering.cpp | 96 ++---
llvm/lib/Target/M68k/M68kISelLowering.h | 18 +-
llvm/lib/Target/M68k/M68kMachineFunction.h | 16 +-
llvm/lib/Target/MSP430/MSP430ISelLowering.cpp | 71 ++-
llvm/lib/Target/MSP430/MSP430ISelLowering.h | 26 +-
.../Mips/MCTargetDesc/MipsInstPrinter.cpp | 4 +-
llvm/lib/Target/Mips/MipsBranchExpansion.cpp | 23 +-
llvm/lib/Target/Mips/MipsCallLowering.cpp | 2 +-
llvm/lib/Target/Mips/MipsISelLowering.cpp | 57 ++-
llvm/lib/Target/Mips/MipsISelLowering.h | 14 +-
.../MCTargetDesc/NVPTXTargetStreamer.cpp | 4 +-
.../NVPTX/MCTargetDesc/NVPTXTargetStreamer.h | 6 +-
llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp | 14 +-
llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp | 16 +-
llvm/lib/Target/NVPTX/NVPTXISelLowering.h | 5 +-
llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp | 2 +-
.../PowerPC/MCTargetDesc/PPCInstPrinter.cpp | 2 +-
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 2 +-
.../Target/PowerPC/PPCBranchCoalescing.cpp | 39 +-
llvm/lib/Target/PowerPC/PPCFrameLowering.cpp | 4 +-
llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 16 +-
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 112 +++--
llvm/lib/Target/PowerPC/PPCISelLowering.h | 80 ++--
.../Target/PowerPC/PPCMachineFunctionInfo.h | 51 ++-
.../Target/PowerPC/PPCTargetTransformInfo.cpp | 12 +-
.../Target/RISCV/GISel/RISCVCallLowering.cpp | 2 +-
.../RISCV/MCTargetDesc/RISCVInstPrinter.cpp | 4 +-
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 49 ++-
llvm/lib/Target/RISCV/RISCVISelLowering.h | 8 +-
.../Target/RISCV/RISCVMachineFunctionInfo.cpp | 2 +-
.../Target/RISCV/RISCVMachineFunctionInfo.h | 35 +-
llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 2 +-
.../SPIRV/SPIRVLegalizeZeroSizeArrays.cpp | 24 +-
.../Sparc/MCTargetDesc/SparcInstPrinter.cpp | 2 +-
llvm/lib/Target/Sparc/SparcISelLowering.cpp | 78 ++--
llvm/lib/Target/Sparc/SparcISelLowering.h | 19 +-
.../MCTargetDesc/SystemZInstPrinterCommon.cpp | 2 +-
.../Target/SystemZ/SystemZISelLowering.cpp | 59 ++-
llvm/lib/Target/SystemZ/SystemZISelLowering.h | 27 +-
llvm/lib/Target/VE/VEISelLowering.cpp | 39 +-
llvm/lib/Target/VE/VEISelLowering.h | 11 +-
.../AsmParser/WebAssemblyAsmTypeCheck.cpp | 11 +-
.../AsmParser/WebAssemblyAsmTypeCheck.h | 6 +-
.../GISel/WebAssemblyCallLowering.cpp | 2 +-
.../WebAssembly/WebAssemblyISelLowering.cpp | 24 +-
.../WebAssembly/WebAssemblyISelLowering.h | 8 +-
llvm/lib/Target/X86/GISel/X86CallLowering.cpp | 2 +-
.../X86/MCTargetDesc/X86ATTInstPrinter.cpp | 2 +-
.../X86/MCTargetDesc/X86InstPrinterCommon.cpp | 4 +-
.../X86/MCTargetDesc/X86IntelInstPrinter.cpp | 2 +-
.../Target/X86/X86CallFrameOptimization.cpp | 19 +-
llvm/lib/Target/X86/X86ISelLowering.h | 19 +-
llvm/lib/Target/X86/X86ISelLoweringCall.cpp | 103 +++--
llvm/lib/Target/X86/X86MachineFunctionInfo.h | 60 +--
llvm/lib/Target/XCore/XCoreISelLowering.cpp | 44 +-
llvm/lib/Target/XCore/XCoreISelLowering.h | 19 +-
.../Xtensa/MCTargetDesc/XtensaInstPrinter.cpp | 6 +-
llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 26 +-
llvm/lib/Target/Xtensa/XtensaISelLowering.h | 8 +-
llvm/lib/Transforms/Coroutines/SpillUtils.cpp | 2 +-
llvm/lib/Transforms/IPO/Attributor.cpp | 10 +-
llvm/lib/Transforms/IPO/BlockExtractor.cpp | 13 +-
llvm/lib/Transforms/IPO/HotColdSplitting.cpp | 12 +-
llvm/lib/Transforms/IPO/Instrumentor.cpp | 14 +-
.../Transforms/IPO/InstrumentorConfigFile.cpp | 6 +-
.../IPO/InstrumentorStubPrinter.cpp | 2 +-
llvm/lib/Transforms/IPO/OpenMPOpt.cpp | 10 +-
llvm/lib/Transforms/IPO/PartialInlining.cpp | 12 +-
llvm/lib/Transforms/IPO/SampleProfile.cpp | 2 +-
.../lib/Transforms/IPO/WholeProgramDevirt.cpp | 58 +--
.../Instrumentation/AddressSanitizer.cpp | 53 ++-
.../ControlHeightReduction.cpp | 40 +-
.../Instrumentation/HWAddressSanitizer.cpp | 2 +-
.../Instrumentation/InstrProfiling.cpp | 16 +-
.../Instrumentation/MemorySanitizer.cpp | 88 ++--
.../Transforms/Scalar/ConstantHoisting.cpp | 23 +-
.../Scalar/ConstraintElimination.cpp | 22 +-
.../Scalar/DeadStoreElimination.cpp | 30 +-
llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 28 +-
llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp | 42 +-
llvm/lib/Transforms/Scalar/GVN.cpp | 18 +-
llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 81 ++--
llvm/lib/Transforms/Scalar/LoopDistribute.cpp | 26 +-
llvm/lib/Transforms/Scalar/LoopFuse.cpp | 57 +--
.../Transforms/Scalar/LoopIdiomRecognize.cpp | 52 ++-
.../lib/Transforms/Scalar/LoopSimplifyCFG.cpp | 37 +-
.../Transforms/Scalar/LoopStrengthReduce.cpp | 202 +++++----
.../Scalar/LowerMatrixIntrinsics.cpp | 25 +-
llvm/lib/Transforms/Scalar/SROA.cpp | 36 +-
llvm/lib/Transforms/Scalar/Scalarizer.cpp | 50 ++-
.../Scalar/TailRecursionElimination.cpp | 13 +-
llvm/lib/Transforms/Utils/CodeExtractor.cpp | 33 +-
llvm/lib/Transforms/Utils/InlineFunction.cpp | 2 +-
llvm/lib/Transforms/Utils/LoopUtils.cpp | 35 +-
.../Transforms/Utils/MemoryTaggingSupport.cpp | 4 +-
.../Utils/PromoteMemoryToRegister.cpp | 24 +-
.../Utils/ScalarEvolutionExpander.cpp | 22 +-
llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | 32 +-
.../Vectorize/LoopVectorizationLegality.cpp | 10 +-
.../Vectorize/LoopVectorizationPlanner.cpp | 2 +-
.../Transforms/Vectorize/LoopVectorize.cpp | 7 +-
.../Transforms/Vectorize/SLPVectorizer.cpp | 243 +++++++----
llvm/tools/dsymutil/MachODebugMapParser.cpp | 18 +-
llvm/tools/dsymutil/Reproducer.cpp | 9 +-
llvm/tools/dsymutil/Reproducer.h | 9 +-
llvm/tools/llvm-cov/SourceCoverageView.h | 15 +-
llvm/tools/llvm-dwarfdump/Coverage.cpp | 26 +-
llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 8 +-
llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp | 10 +-
llvm/tools/llvm-exegesis/lib/Analysis.cpp | 2 +-
.../lib/SchedClassResolution.cpp | 8 +-
.../llvm-exegesis/lib/SchedClassResolution.h | 8 +-
llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 99 ++---
llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 18 +-
llvm/tools/llvm-profgen/PerfReader.cpp | 8 +-
llvm/tools/llvm-profgen/PerfReader.h | 15 +-
llvm/tools/llvm-profgen/ProfileGenerator.cpp | 2 +-
llvm/tools/llvm-reduce/TestRunner.cpp | 16 +-
llvm/tools/llvm-reduce/TestRunner.h | 21 +-
llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp | 12 +-
.../ADT/SmallVectorWithFlagsTest.cpp | 110 ++++-
.../Bitstream/BitstreamWriterTest.cpp | 18 +
.../SelectionDAGNodeConstructionTest.cpp | 42 ++
.../MCJIT/MCJITObjectCacheTest.cpp | 12 +-
.../HLSLSemanticSignaturePackingTest.cpp | 17 +-
.../Frontend/OpenMPIRBuilderTest.cpp | 2 +-
llvm/unittests/IR/LegacyPassManagerTest.cpp | 23 +
.../LoongArch/LoongArchMCDisassemblerTest.cpp | 10 +-
.../ProfileData/DataAccessProfTest.cpp | 7 +-
.../Support/OptimizedStructLayoutTest.cpp | 10 +-
llvm/unittests/Support/YAMLIOTest.cpp | 33 ++
llvm/utils/TableGen/AsmMatcherEmitter.cpp | 43 +-
.../TableGen/Basic/CodeGenIntrinsics.cpp | 18 +-
llvm/utils/TableGen/Basic/CodeGenIntrinsics.h | 71 ++-
.../utils/TableGen/Basic/IntrinsicEmitter.cpp | 43 +-
.../TableGen/Common/CodeGenDAGPatterns.cpp | 5 +-
.../TableGen/Common/CodeGenRegisters.cpp | 158 +++----
llvm/utils/TableGen/Common/CodeGenRegisters.h | 76 ++--
llvm/utils/TableGen/Common/CodeGenTarget.cpp | 3 +-
llvm/utils/TableGen/Common/CodeGenTarget.h | 14 +-
.../Common/GlobalISel/MatchTable/Matchers.cpp | 9 +-
.../Common/GlobalISel/MatchTable/Matchers.h | 22 +-
.../Common/GlobalISel/PatternParser.cpp | 8 +-
.../TableGen/Common/InstructionEncoding.cpp | 6 +-
.../TableGen/Common/InstructionEncoding.h | 8 +-
.../TableGen/Common/VarLenCodeEmitterGen.cpp | 6 +-
.../TableGen/Common/VarLenCodeEmitterGen.h | 10 +-
llvm/utils/TableGen/DecoderEmitter.cpp | 25 +-
llvm/utils/TableGen/GlobalISelEmitter.cpp | 2 +-
llvm/utils/TableGen/RegisterInfoEmitter.cpp | 39 +-
.../utils/TableGen/SearchableTableEmitter.cpp | 36 +-
.../transform-opt/mlir-transform-opt.cpp | 13 +-
mlir/include/mlir/ABI/ABIRewriteContext.h | 9 +-
.../mlir/Analysis/Presburger/Simplex.h | 12 +-
.../IR/BufferizableOpInterface.h | 10 +-
.../Dialect/LLVMIR/BasicPtxBuilderInterface.h | 20 +-
.../Dialect/Linalg/Transforms/Transforms.h | 47 +-
mlir/include/mlir/Dialect/Shard/IR/ShardOps.h | 4 +-
.../Shard/Interfaces/ShardingInterface.h | 13 +-
.../mlir/Dialect/SparseTensor/Utils/Merger.h | 7 +-
.../mlir/Dialect/Tosa/Utils/ConversionUtils.h | 4 +-
.../mlir/Dialect/Tosa/Utils/ShapeUtils.h | 62 +--
.../Dialect/Transform/IR/TransformDialect.h | 10 +-
.../mlir/ExecutionEngine/ExecutionEngine.h | 6 +-
.../mlir/Interfaces/InferTypeOpInterface.h | 38 +-
.../mlir/Support/CyclicReplacerCache.h | 12 +-
mlir/include/mlir/TableGen/Class.h | 9 +-
mlir/include/mlir/TableGen/Operator.h | 9 +-
mlir/include/mlir/Tools/PDLL/ODS/Operation.h | 8 +-
mlir/lib/Analysis/Presburger/Simplex.cpp | 51 +--
mlir/lib/AsmParser/AffineParser.cpp | 14 +-
mlir/lib/Bytecode/Reader/BytecodeReader.cpp | 60 +--
.../IR/BufferizableOpInterface.cpp | 4 +-
.../Transforms/OneShotModuleBufferize.cpp | 2 +-
.../LLVMIR/IR/BasicPtxBuilderInterface.cpp | 30 +-
.../Linalg/Transforms/BlockPackMatmul.cpp | 26 +-
.../Linalg/Transforms/PadTilingInterface.cpp | 6 +-
.../Linalg/Transforms/Vectorization.cpp | 16 +-
.../NVGPU/TransformOps/NVGPUTransformOps.cpp | 16 +-
.../Dialect/OpenACC/Transforms/ACCCGToGPU.cpp | 96 +++--
.../Shard/Interfaces/ShardingInterface.cpp | 4 +-
.../Shard/Transforms/ShardingPropagation.cpp | 9 +-
.../SparseTensor/IR/Detail/DimLvlMap.cpp | 5 +-
.../SparseTensor/IR/Detail/DimLvlMap.h | 6 +-
.../lib/Dialect/SparseTensor/Utils/Merger.cpp | 3 +-
.../Tosa/Transforms/TosaInferShapes.cpp | 2 +-
mlir/lib/ExecutionEngine/ExecutionEngine.cpp | 6 +-
mlir/lib/IR/MLIRContext.cpp | 54 ++-
mlir/lib/Interfaces/InferTypeOpInterface.cpp | 11 +-
mlir/lib/TableGen/Class.cpp | 5 +-
mlir/lib/TableGen/Operator.cpp | 39 +-
mlir/lib/Target/Cpp/TranslateToCpp.cpp | 20 +-
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 31 +-
mlir/lib/Tools/PDLL/ODS/Operation.cpp | 5 +-
.../TestOneShotModuleBufferize.cpp | 2 +-
mlir/unittests/Dialect/CMakeLists.txt | 1 +
mlir/unittests/Dialect/Tosa/CMakeLists.txt | 9 +
.../unittests/Dialect/Tosa/ShapeUtilsTest.cpp | 46 ++
.../Interfaces/InferTypeOpInterfaceTest.cpp | 32 ++
polly/include/polly/ScopInfo.h | 69 +--
polly/lib/Analysis/ScopInfo.cpp | 13 +-
861 files changed, 12978 insertions(+), 8706 deletions(-)
create mode 100644 mlir/unittests/Dialect/Tosa/CMakeLists.txt
create mode 100644 mlir/unittests/Dialect/Tosa/ShapeUtilsTest.cpp
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index c41ad06027f64..22fdf5a5beaef 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -39,6 +39,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
@@ -236,6 +237,24 @@ class BinaryFunction {
bool HadNegateRAState{false};
bool InitialRAState{false};
+ /// False if the function is too complex to reconstruct its control
+ /// flow graph.
+ /// In relocation mode we still disassemble and re-assemble such functions.
+ bool IsSimple{true};
+
+ /// Indication that the function should be ignored for optimization purposes.
+ /// If we can skip emission of some functions, then ignored functions could
+ /// be not fully disassembled and will not be emitted.
+ bool IsIgnored{false};
+
+ /// Pseudo functions should not be disassembled or emitted.
+ bool IsPseudo{false};
+
+ /// True if the original function code has all necessary relocations to track
+ /// addresses of functions emitted to new locations. Typically set for
+ /// functions that we are not going to emit.
+ bool HasExternalRefRelocations{false};
+
/// A list of symbols associated with the function entry point.
///
/// Multiple symbols would typically result from identical code-folding
@@ -245,7 +264,7 @@ class BinaryFunction {
/// The list of names this function is known under. Used for fuzzy-matching
/// the function to its name in a profile, command line, etc.
- SmallVector<std::string, 0> Aliases;
+ SmallVectorWithFlags<std::string, 0, 4> Aliases;
/// Containing section in the input file.
BinarySection *OriginSection = nullptr;
@@ -315,67 +334,23 @@ class BinaryFunction {
/// is a global symbol corresponding to an external entry point.
DenseMap<const MCSymbol *, MCSymbol *> SecondaryEntryPoints;
- /// False if the function is too complex to reconstruct its control
- /// flow graph.
- /// In relocation mode we still disassemble and re-assemble such functions.
- bool IsSimple{true};
-
- /// Indication that the function should be ignored for optimization purposes.
- /// If we can skip emission of some functions, then ignored functions could
- /// be not fully disassembled and will not be emitted.
- bool IsIgnored{false};
-
- /// Pseudo functions should not be disassembled or emitted.
- bool IsPseudo{false};
-
- /// True if the original function code has all necessary relocations to track
- /// addresses of functions emitted to new locations. Typically set for
- /// functions that we are not going to emit.
- bool HasExternalRefRelocations{false};
-
- /// True if the function has an indirect branch with unknown destination.
- bool HasUnknownControlFlow{false};
-
- /// The code from inside the function references one of the code locations
- /// from the same function as a data, i.e. it's possible the label is used
- /// inside an address calculation or could be referenced from outside.
- bool HasInternalLabelReference{false};
-
- /// In AArch64, preserve nops to maintain code equal to input (assuming no
- /// optimizations are done).
- bool PreserveNops{false};
-
- /// Indicate if this function has associated exception handling metadata.
- bool HasEHRanges{false};
-
- /// True if the function uses DW_CFA_GNU_args_size CFIs.
- bool UsesGnuArgsSize{false};
-
- /// True if the function might have a profile available externally.
- /// Used to check if processing of the function is required under certain
- /// conditions.
- bool HasProfileAvailable{false};
-
- bool HasMemoryProfile{false};
-
- /// Execution halts whenever this function is entered.
- bool TrapsOnEntry{false};
+ bool getHasMemoryProfileFlag() const { return Aliases.getFlag(0); }
+ void setHasMemoryProfileFlag(bool Value) { Aliases.setFlag(0, Value); }
/// True if the function is a fragment of another function. This means that
/// this function could only be entered via its parent or one of its sibling
/// fragments. It could be entered at any basic block. It can also return
/// the control to any basic block of its parent or its sibling.
- bool IsFragment{false};
+ bool getIsFragmentFlag() const { return Aliases.getFlag(1); }
+ void setIsFragmentFlag(bool Value) { Aliases.setFlag(1, Value); }
/// Indicate that the function body has SDT marker
- bool HasSDTMarker{false};
+ bool getHasSDTMarkerFlag() const { return Aliases.getFlag(2); }
+ void setHasSDTMarkerFlag(bool Value) { Aliases.setFlag(2, Value); }
/// Indicate that the function body has Pseudo Probe
- bool HasPseudoProbe{BC.getUniqueSectionByName(".pseudo_probe_desc") &&
- BC.getUniqueSectionByName(".pseudo_probe")};
-
- /// True if the function uses ORC format for stack unwinding.
- bool HasORC{false};
+ bool getHasPseudoProbeFlag() const { return Aliases.getFlag(3); }
+ void setHasPseudoProbeFlag(bool Value) { Aliases.setFlag(3, Value); }
/// True if the function contains explicit or implicit indirect branch to its
/// split fragments, e.g., split jump table, landing pad in split fragment
@@ -450,6 +425,24 @@ class BinaryFunction {
/// been adjusted by the profile inference algorithm.
bool HasInferredProfile{false};
+ /// True if the function has an indirect branch with unknown destination.
+ bool HasUnknownControlFlow{false};
+
+ /// The code from inside the function references one of the code locations
+ /// from the same function as a data, i.e. it's possible the label is used
+ /// inside an address calculation or could be referenced from outside.
+ bool HasInternalLabelReference{false};
+
+ /// In AArch64, preserve nops to maintain code equal to input (assuming no
+ /// optimizations are done).
+ bool PreserveNops{false};
+
+ /// Indicate if this function has associated exception handling metadata.
+ bool HasEHRanges{false};
+
+ /// True if the function uses DW_CFA_GNU_args_size CFIs.
+ bool UsesGnuArgsSize{false};
+
/// For functions with mismatched profile we store all call profile
/// information at a function level (as opposed to tying it to
/// specific call sites).
@@ -486,6 +479,17 @@ class BinaryFunction {
/// Function is referenced by a non-control flow instruction.
bool HasAddressTaken{false};
+ /// True if the function might have a profile available externally.
+ /// Used to check if processing of the function is required under certain
+ /// conditions.
+ bool HasProfileAvailable{false};
+
+ /// Execution halts whenever this function is entered.
+ bool TrapsOnEntry{false};
+
+ /// True if the function uses ORC format for stack unwinding.
+ bool HasORC{false};
+
/// Get basic block index assuming it belongs to this function.
unsigned getIndex(const BinaryBasicBlock *BB) const {
assert(BB->getIndex() < BasicBlocks.size());
@@ -716,7 +720,8 @@ class BinaryFunction {
/// parent fragment to \p BF.
void addParentFragment(BinaryFunction &BF) {
assert(this != &BF);
- assert(IsFragment && "function must be a fragment to have a parent");
+ assert(getIsFragmentFlag() &&
+ "function must be a fragment to have a parent");
ParentFragments.insert(&BF);
}
@@ -770,7 +775,11 @@ class BinaryFunction {
/// Creation should be handled by RewriteInstance or BinaryContext
BinaryFunction(const std::string &Name, BinarySection &Section,
uint64_t Address, uint64_t Size, BinaryContext &BC)
- : OriginSection(&Section), Address(Address), Size(Size), BC(BC),
+ : Aliases(decltype(Aliases)::withFlags(
+ (unsigned(bool(BC.getUniqueSectionByName(".pseudo_probe_desc") &&
+ BC.getUniqueSectionByName(".pseudo_probe")))
+ << 3))),
+ OriginSection(&Section), Address(Address), Size(Size), BC(BC),
FunctionNumber(++Count) {
Symbols.push_back(BC.Ctx->getOrCreateSymbol(Name));
}
@@ -778,7 +787,12 @@ class BinaryFunction {
/// This constructor is used to create an injected function, i.e. a function
/// that didn't originate in the input file.
BinaryFunction(const std::string &Name, BinaryContext &BC, bool IsSimple)
- : Address(0), Size(0), BC(BC), IsSimple(IsSimple),
+ : IsSimple(IsSimple),
+ Aliases(decltype(Aliases)::withFlags(
+ (unsigned(bool(BC.getUniqueSectionByName(".pseudo_probe_desc") &&
+ BC.getUniqueSectionByName(".pseudo_probe")))
+ << 3))),
+ Address(0), Size(0), BC(BC),
CodeSectionName(BC.getInjectedCodeSectionName()),
ColdCodeSectionName(BC.getInjectedColdCodeSectionName()),
FunctionNumber(++Count) {
@@ -1498,7 +1512,7 @@ class BinaryFunction {
/// but not yet populated into the function.
bool hasProfileAvailable() const { return HasProfileAvailable; }
- bool hasMemoryProfile() const { return HasMemoryProfile; }
+ bool hasMemoryProfile() const { return getHasMemoryProfileFlag(); }
/// Return true if the body of the function was merged into another function.
bool isFolded() const { return FoldedIntoFunction != nullptr; }
@@ -1525,10 +1539,10 @@ class BinaryFunction {
bool hasJumpTables() const { return !JumpTables.empty(); }
/// Return true if the function has SDT marker
- bool hasSDTMarker() const { return HasSDTMarker; }
+ bool hasSDTMarker() const { return getHasSDTMarkerFlag(); }
/// Return true if the function has Pseudo Probe
- bool hasPseudoProbe() const { return HasPseudoProbe; }
+ bool hasPseudoProbe() const { return getHasPseudoProbeFlag(); }
/// Return true if the function uses ORC format for stack unwinding.
bool hasORC() const { return HasORC; }
@@ -1964,7 +1978,7 @@ class BinaryFunction {
IsAnonymous = V;
}
- void setHasSDTMarker(bool V) { HasSDTMarker = V; }
+ void setHasSDTMarker(bool V) { setHasSDTMarkerFlag(V); }
/// Mark the function as using ORC format for stack unwinding.
void setHasORC(bool V) { HasORC = V; }
@@ -2032,7 +2046,7 @@ class BinaryFunction {
}
/// Return true if the function is a secondary fragment of another function.
- bool isFragment() const { return IsFragment; }
+ bool isFragment() const { return getIsFragmentFlag(); }
/// Returns if this function is a child of \p Other function.
bool isChildOf(const BinaryFunction &Other) const {
diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index b06b0d90a7aee..8fa86c1ee3228 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/MC/MCDwarf.h"
@@ -517,7 +518,7 @@ class DebugStrOffsetsWriter {
}
bool isStrOffsetsSectionModified() const {
- return StrOffsetSectionWasModified;
+ return getStrOffsetSectionWasModified();
}
private:
@@ -526,9 +527,12 @@ class DebugStrOffsetsWriter {
std::map<uint32_t, uint64_t> IndexToAddressMap;
[[maybe_unused]]
DenseSet<uint64_t> DebugStrOffsetFinalized;
- SmallVector<uint64_t, 5> StrOffsets;
+ llvm::SmallVectorWithFlags<uint64_t, 5> StrOffsets;
std::unordered_map<uint64_t, uint64_t> ProcessedBaseOffsets;
- bool StrOffsetSectionWasModified = false;
+ bool getStrOffsetSectionWasModified() const { return StrOffsets.getFlag(0); }
+ void setStrOffsetSectionWasModified(bool Value) {
+ StrOffsets.setFlag(0, Value);
+ }
BinaryContext &BC;
};
diff --git a/bolt/include/bolt/Core/DebugNames.h b/bolt/include/bolt/Core/DebugNames.h
index a87d4c3c67b2c..099816d231263 100644
--- a/bolt/include/bolt/Core/DebugNames.h
+++ b/bolt/include/bolt/Core/DebugNames.h
@@ -15,6 +15,7 @@
#define BOLT_CORE_DEBUG_NAMES_H
#include "bolt/Core/DebugData.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/AccelTable.h"
#include <mutex>
@@ -67,7 +68,7 @@ class DWARF5AcceleratorTable {
/// Emit Accelerator table.
void emitAccelTable();
/// Returns true if the table was created.
- bool isCreated() const { return NeedToCreate; }
+ bool isCreated() const { return getNeedToCreate(); }
/// Returns buffer containing the accelerator table.
std::unique_ptr<DebugBufferVector> releaseBuffer() {
return std::move(FullTableBuffer);
@@ -89,7 +90,8 @@ class DWARF5AcceleratorTable {
private:
BinaryContext &BC;
- bool NeedToCreate = false;
+ bool getNeedToCreate() const { return AbbreviationsVector.getFlag(0); }
+ void setNeedToCreate(bool Value) { AbbreviationsVector.setFlag(0, Value); }
BumpPtrAllocator Allocator;
DebugStrWriter &MainBinaryStrWriter;
StringRef StrSection;
@@ -102,7 +104,8 @@ class DWARF5AcceleratorTable {
/// multiple TUs with the same hash.
DenseMap<uint64_t, uint32_t> TUHashToIndexMap;
/// Track whether AcceleratorTable have been preallocated.
- bool Preallocated = false;
+ bool getPreallocated() const { return AbbreviationsVector.getFlag(1); }
+ void setPreallocated(bool Value) { AbbreviationsVector.setFlag(1, Value); }
/// Represents a group of entries with identical name (and hence, hash value).
struct HashData {
uint64_t StrOffset;
@@ -128,7 +131,7 @@ class DWARF5AcceleratorTable {
/// FoldingSet that uniques the abbreviations.
FoldingSet<DebugNamesAbbrev> AbbreviationsSet;
/// Vector containing DebugNames abbreviations for iteration in order.
- SmallVector<DebugNamesAbbrev *, 5> AbbreviationsVector;
+ llvm::SmallVectorWithFlags<DebugNamesAbbrev *, 5, 2> AbbreviationsVector;
/// The bump allocator to use when creating DIEAbbrev objects in the uniqued
/// storage container.
BumpPtrAllocator Alloc;
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 710a61f19e340..e8b6c0443c52b 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -16,6 +16,7 @@
#include "bolt/Profile/DataReader.h"
#include "bolt/Profile/YAMLProfileWriter.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Program.h"
@@ -163,9 +164,10 @@ class DataAggregator : public DataReader {
/// Perf.data or pre-aggregated inputs to aggregate and merge into this
/// reader. The first entry is the primary profile input.
- SmallVector<std::string, 1> InputFilenames;
+ llvm::SmallVectorWithFlags<std::string, 1> InputFilenames;
- bool Parsed{false};
+ bool getParsed() const { return InputFilenames.getFlag(0); }
+ void setParsed(bool Value) { InputFilenames.setFlag(0, Value); }
/// Filter pre-aggregated entries belonging to a DSO with this buildid.
/// Set when processing a shared library, empty implies main binary.
@@ -193,11 +195,14 @@ class DataAggregator : public DataReader {
static constexpr StringLiteral PerfProcessTypeNames[] = {
"BUILDIDS", "MAIN", "MEM", "MMAP", "TASK"};
+ explicit PerfProcessInfo(PerfProcessType Type) : Type(Type) {}
+
enum PerfProcessType Type;
- bool IsFinished{false};
+ bool getIsFinished() const { return StderrPath.getFlag(0); }
+ void setIsFinished(bool Value) { StderrPath.setFlag(0, Value); }
sys::ProcessInfo PI{};
SmallVector<char, 256> StdoutPath{};
- SmallVector<char, 256> StderrPath{};
+ llvm::SmallVectorWithFlags<char, 256> StderrPath{};
/// Helper variables for parsing perfscript profile.
/// Length: Total size of the content from \p Offset.
@@ -207,11 +212,11 @@ class DataAggregator : public DataReader {
};
/// Process info for spawned processes
- PerfProcessInfo BuildIDProcessInfo = {PerfProcessType::BUILDIDS};
- PerfProcessInfo MainEventsPPI = {PerfProcessType::MAIN_EVENTS};
- PerfProcessInfo MemEventsPPI = {PerfProcessType::MEM_EVENTS};
- PerfProcessInfo MMapEventsPPI = {PerfProcessType::MMAP_EVENTS};
- PerfProcessInfo TaskEventsPPI = {PerfProcessType::TASK_EVENTS};
+ PerfProcessInfo BuildIDProcessInfo{PerfProcessType::BUILDIDS};
+ PerfProcessInfo MainEventsPPI{PerfProcessType::MAIN_EVENTS};
+ PerfProcessInfo MemEventsPPI{PerfProcessType::MEM_EVENTS};
+ PerfProcessInfo MMapEventsPPI{PerfProcessType::MMAP_EVENTS};
+ PerfProcessInfo TaskEventsPPI{PerfProcessType::TASK_EVENTS};
/// Kernel VM starts at fixed based address
/// https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txt
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 8985ca30433a7..7f3941ab5c925 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -446,7 +446,7 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation) {
OS << "\n Unknown CF : true";
if (getPersonalityFunction())
OS << "\n Personality : " << getPersonalityFunction()->getName();
- if (IsFragment)
+ if (getIsFragmentFlag())
OS << "\n IsFragment : true";
if (isFolded())
OS << "\n FoldedInto : " << *getFoldedIntoFunction();
@@ -4605,7 +4605,7 @@ DebugAddressRangesVector BinaryFunction::getOutputAddressRanges() const {
if (isFolded())
return OutputRanges;
- if (IsFragment)
+ if (getIsFragmentFlag())
return OutputRanges;
OutputRanges.emplace_back(getOutputAddress(),
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index df8f7aa33485c..d95abf9bb968a 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -918,7 +918,7 @@ void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint64_t Address,
"Cannot update address map since debug_str_offsets was already "
"finalized for this CU.");
IndexToAddressMap[Index] = Address;
- StrOffsetSectionWasModified = true;
+ setStrOffsetSectionWasModified(true);
}
void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit,
@@ -941,7 +941,8 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit,
Die.findAttribute(dwarf::DW_AT_str_offsets_base);
auto RetVal = ProcessedBaseOffsets.find(*Val);
// Handling reuse of str-offsets section.
- if (RetVal == ProcessedBaseOffsets.end() || StrOffsetSectionWasModified) {
+ if (RetVal == ProcessedBaseOffsets.end() ||
+ getStrOffsetSectionWasModified()) {
initialize(Unit);
// Update String Offsets that were modified.
for (const auto &Entry : IndexToAddressMap)
@@ -974,7 +975,7 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit,
DIEInteger(RetVal->second));
}
- StrOffsetSectionWasModified = false;
+ setStrOffsetSectionWasModified(false);
assert(DebugStrOffsetFinalized.insert(Unit.getOffset()).second &&
"debug_str_offsets was already finalized for this CU.");
clear();
diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp
index 829200e9d182c..aa3fdf956082f 100644
--- a/bolt/lib/Core/DebugNames.cpp
+++ b/bolt/lib/Core/DebugNames.cpp
@@ -23,8 +23,8 @@ DWARF5AcceleratorTable::DWARF5AcceleratorTable(
const bool CreateDebugNames, BinaryContext &BC,
DebugStrWriter &MainBinaryStrWriter)
: BC(BC), MainBinaryStrWriter(MainBinaryStrWriter) {
- NeedToCreate = CreateDebugNames || BC.getDebugNamesSection();
- if (!NeedToCreate)
+ setNeedToCreate(CreateDebugNames || BC.getDebugNamesSection());
+ if (!getNeedToCreate())
return;
FullTableBuffer = std::make_unique<DebugStrBufferVector>();
FullTableStream = std::make_unique<raw_svector_ostream>(*FullTableBuffer);
@@ -47,7 +47,7 @@ DWARF5AcceleratorTable::DWARF5AcceleratorTable(
Error Err = Error::success();
const char *CStr = StrData.getCStr(&Offset, &Err);
if (Err) {
- NeedToCreate = false;
+ setNeedToCreate(false);
BC.errs() << "BOLT-WARNING: [internal-dwarf-error]: Could not extract "
"string from .debug_str section at offset: "
<< Twine::utohexstr(StrOffset) << ".\n";
@@ -98,7 +98,7 @@ void DWARF5AcceleratorTable::preAllocateUnits(DWARFContext &DwCtx) {
}
}
}
- Preallocated = true;
+ setPreallocated(true);
}
void DWARF5AcceleratorTable::setCurrentUnit(DWARFUnit &Unit,
@@ -137,7 +137,7 @@ DWARF5AcceleratorTable::getCrossCUDie(uint64_t Offset) {
void DWARF5AcceleratorTable::addUnit(DWARFUnit &Unit,
const std::optional<uint64_t> &DWOID) {
StrSection = Unit.getStringSection();
- if (Preallocated) {
+ if (getPreallocated()) {
if (!Unit.isTypeUnit() && !DWOID) {
CUList.push_back(CurrentUnitOffset);
}
@@ -302,7 +302,7 @@ uint32_t DWARF5AcceleratorTable::getUnitID(const DWARFUnit &Unit,
}
return LocalTUList.size() - 1;
}
- if (Preallocated && DWOID) {
+ if (getPreallocated() && DWOID) {
auto Iter = CUOffsetsToPatch.find(*DWOID);
assert(Iter != CUOffsetsToPatch.end() && "DWO ID not preallocated");
return Iter->second;
@@ -450,7 +450,7 @@ DWARF5AcceleratorTable::addAccelTableEntry(
DWARFUnit &Unit, const DIE &Die, const std::optional<uint64_t> &DWOID,
const uint32_t NumberParentsInChain,
std::optional<BOLTDWARF5AccelTableData *> &Parent) {
- if (Unit.getVersion() < 5 || !NeedToCreate)
+ if (Unit.getVersion() < 5 || !getNeedToCreate())
return std::nullopt;
std::string NameToUse = "";
@@ -538,7 +538,7 @@ static unsigned getTypeUnitKey(const BOLTDWARF5AccelTableData *Entry) {
/// Bucket code as in: AccelTableBase::finalize()
void DWARF5AcceleratorTable::finalize() {
- if (!NeedToCreate)
+ if (!getNeedToCreate())
return;
// Figure out how many buckets we need, then compute the bucket contents and
// the final ordering. The hashes and offsets can be emitted by walking these
@@ -895,7 +895,7 @@ void DWARF5AcceleratorTable::emitAugmentationString() const {
FullTableStream->write(AugStringBuffer->data(), AugStringBuffer->size());
}
void DWARF5AcceleratorTable::emitAccelTable() {
- if (!NeedToCreate)
+ if (!getNeedToCreate())
return;
finalize();
populateAbbrevsMap();
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index ca1c18dcaadd3..9319ca57acda4 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -184,7 +184,7 @@ void DataAggregator::mergeFrom(const DataAggregator &Other) {
NumInvalidTraces += Other.NumInvalidTraces;
NumLongRangeTraces += Other.NumLongRangeTraces;
NumTotalSamples += Other.NumTotalSamples;
- Parsed = true;
+ setParsed(true);
}
void DataAggregator::markFunctionsWithProfile() {
@@ -328,14 +328,20 @@ Error DataAggregator::launchPerfProcess(StringRef Name, PerfProcessInfo &PPI,
Argv.push_back("-i");
Argv.push_back(Filename.c_str());
- for (auto [Ext, Path] : {std::make_pair("out", &PPI.StdoutPath),
- std::make_pair("err", &PPI.StderrPath)}) {
+ auto CreateTempFile = [&](StringRef Ext, auto &Path) -> Error {
+ SmallVector<char, 256> TemporaryPath;
if (std::error_code Errc =
- sys::fs::createTemporaryFile("perf.script", Ext, *Path))
+ sys::fs::createTemporaryFile("perf.script", Ext, TemporaryPath))
return createStringError(Errc, "failed to create temporary file %s",
- Path->data());
- TempFiles.push_back(Path->data());
- }
+ TemporaryPath.data());
+ Path.assign(TemporaryPath.begin(), TemporaryPath.end());
+ TempFiles.push_back(Path.data());
+ return Error::success();
+ };
+ if (Error E = CreateTempFile("out", PPI.StdoutPath))
+ return E;
+ if (Error E = CreateTempFile("err", PPI.StderrPath))
+ return E;
std::optional<StringRef> Redirects[] = {
std::nullopt, // Stdin
@@ -893,19 +899,19 @@ Error DataAggregator::parseAllInputs(BinaryContext &BC) {
inconvertibleErrorCode(), "%s: %s%s", Job->DA->Filename.c_str(),
Job->DiagBuffer.c_str(), toString(std::move(E)).c_str());
}
- Job->DA->Parsed = true;
+ Job->DA->setParsed(true);
return Error::success();
});
parallel::strategy = SavedStrategy;
for (AggregatorJob *Job : Jobs) {
- if (Job->DA->Parsed)
+ if (Job->DA->getParsed())
mergeFrom(*Job->DA);
delete Job->DA;
delete Job;
}
- if (!Parsed)
+ if (!getParsed())
return ParseErrors;
handleAllErrors(std::move(ParseErrors), [](const ErrorInfoBase &EI) {
errs() << "PERF2BOLT-WARNING: " << EI.message() << "\n";
diff --git a/bolt/lib/Profile/DataReader.cpp b/bolt/lib/Profile/DataReader.cpp
index 7fcaffd763ad3..8d5719e13f839 100644
--- a/bolt/lib/Profile/DataReader.cpp
+++ b/bolt/lib/Profile/DataReader.cpp
@@ -314,7 +314,7 @@ Error DataReader::readProfilePreCFG(BinaryContext &BC) {
else
MemAccessProfile.NextInstrOffset = II->first;
}
- Function.HasMemoryProfile = true;
+ Function.setHasMemoryProfileFlag(true);
}
return Error::success();
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 829dc998d623b..964ec219fdbac 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -1423,7 +1423,7 @@ void RewriteInstance::discoverFileObjects() {
BC->errs() << '\n';
}
BC->HasSplitFunctions = true;
- BF->IsFragment = true;
+ BF->setIsFragmentFlag(true);
}
if (!AlternativeName.empty())
diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp
index a436200c81e13..1cc94979439f7 100644
--- a/bolt/unittests/Core/BinaryContext.cpp
+++ b/bolt/unittests/Core/BinaryContext.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "bolt/Core/BinaryContext.h"
+#include "bolt/Core/BinaryFunction.h"
#include "bolt/Rewrite/RewriteInstance.h"
#include "bolt/Utils/CommandLineOpts.h"
#include "llvm/BinaryFormat/ELF.h"
@@ -73,6 +74,25 @@ struct BinaryContextTester : public testing::TestWithParam<Triple::ArchType> {
} // namespace
+TEST_P(BinaryContextTester, FunctionMetadataFlags) {
+ BC->registerOrUpdateSection(".pseudo_probe_desc", ELF::SHT_PROGBITS, 0);
+ BC->registerOrUpdateSection(".pseudo_probe", ELF::SHT_PROGBITS, 0);
+ BinaryFunction *Function = BC->createInjectedBinaryFunction("metadata", true);
+ ASSERT_TRUE(Function->hasPseudoProbe());
+ EXPECT_FALSE(Function->hasMemoryProfile());
+ EXPECT_FALSE(Function->isFragment());
+ Function->setHasSDTMarker(true);
+ EXPECT_TRUE(Function->hasSDTMarker());
+ EXPECT_TRUE(Function->hasPseudoProbe());
+ EXPECT_FALSE(Function->hasMemoryProfile());
+ EXPECT_FALSE(Function->isFragment());
+ EXPECT_TRUE(Function->isSimple());
+ EXPECT_TRUE(Function->hasName("metadata"));
+ Function->setHasSDTMarker(false);
+ EXPECT_FALSE(Function->hasSDTMarker());
+ EXPECT_TRUE(Function->hasPseudoProbe());
+}
+
#ifdef X86_AVAILABLE
INSTANTIATE_TEST_SUITE_P(X86, BinaryContextTester,
diff --git a/clang-tools-extra/clang-move/Move.cpp b/clang-tools-extra/clang-move/Move.cpp
index 1f966b3119620..721a55ae9f207 100644
--- a/clang-tools-extra/clang-move/Move.cpp
+++ b/clang-tools-extra/clang-move/Move.cpp
@@ -763,7 +763,7 @@ void ClangMoveTool::removeDeclsInOldFiles() {
for (auto &FileAndReplacements : Context->FileToReplacements) {
StringRef FilePath = FileAndReplacements.first;
// Add #include of new header to old header.
- if (Context->Spec.OldDependOnNew &&
+ if (Context->Spec.getOldDependOnNew() &&
MakeAbsolutePath(SM, FilePath) ==
makeAbsolutePath(Context->Spec.OldHeader)) {
// FIXME: Minimize the include path like clang-include-fixer.
@@ -827,7 +827,7 @@ void ClangMoveTool::moveDeclsToNewFiles() {
if (!Context->Spec.NewHeader.empty()) {
std::string OldHeaderInclude =
- Context->Spec.NewDependOnOld
+ Context->Spec.getNewDependOnOld()
? "#include \"" + Context->Spec.OldHeader + "\"\n"
: "";
Context->FileToReplacements[Context->Spec.NewHeader] =
diff --git a/clang-tools-extra/clang-move/Move.h b/clang-tools-extra/clang-move/Move.h
index ba613abc03e19..316a5efd8f554 100644
--- a/clang-tools-extra/clang-move/Move.h
+++ b/clang-tools-extra/clang-move/Move.h
@@ -15,6 +15,7 @@
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <map>
@@ -59,7 +60,7 @@ class DeclarationReporter {
// declarations.
struct MoveDefinitionSpec {
// The list of fully qualified names, e.g. Foo, a::Foo, b::Foo.
- SmallVector<std::string, 4> Names;
+ llvm::SmallVectorWithFlags<std::string, 4, 2> Names;
// The file path of old header, can be relative path and absolute path.
std::string OldHeader;
// The file path of old cc, can be relative path and absolute path.
@@ -70,10 +71,12 @@ struct MoveDefinitionSpec {
std::string NewCC;
// Whether old.h depends on new.h. If true, #include "new.h" will be added
// in old.h.
- bool OldDependOnNew = false;
+ bool getOldDependOnNew() const { return Names.getFlag(0); }
+ void setOldDependOnNew(bool Value) { Names.setFlag(0, Value); }
// Whether new.h depends on old.h. If true, #include "old.h" will be added
// in new.h.
- bool NewDependOnOld = false;
+ bool getNewDependOnOld() const { return Names.getFlag(1); }
+ void setNewDependOnOld(bool Value) { Names.setFlag(1, Value); }
};
// A Context which contains extra options which are used in ClangMoveTool.
diff --git a/clang-tools-extra/clang-move/tool/ClangMove.cpp b/clang-tools-extra/clang-move/tool/ClangMove.cpp
index d36ce89b611f5..d239448043f68 100644
--- a/clang-tools-extra/clang-move/tool/ClangMove.cpp
+++ b/clang-tools-extra/clang-move/tool/ClangMove.cpp
@@ -117,13 +117,13 @@ int main(int argc, const char **argv) {
Tool.appendArgumentsAdjuster(tooling::getInsertArgumentAdjuster(
"-fparse-all-comments", tooling::ArgumentInsertPosition::BEGIN));
move::MoveDefinitionSpec Spec;
- Spec.Names = {Names.begin(), Names.end()};
+ Spec.Names.assign(Names.begin(), Names.end());
Spec.OldHeader = OldHeader;
Spec.NewHeader = NewHeader;
Spec.OldCC = OldCC;
Spec.NewCC = NewCC;
- Spec.OldDependOnNew = OldDependOnNew;
- Spec.NewDependOnOld = NewDependOnOld;
+ Spec.setOldDependOnNew(OldDependOnNew);
+ Spec.setNewDependOnOld(NewDependOnOld);
llvm::SmallString<128> InitialDirectory;
if (std::error_code EC = llvm::sys::fs::current_path(InitialDirectory))
diff --git a/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp
index e976a7eecbfcb..525f9fc5accc0 100644
--- a/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include <initializer_list>
#include <optional>
@@ -30,7 +31,8 @@ class BoostReplacer : public UseRangesCheck::Replacer {
public:
BoostReplacer(ArrayRef<UseRangesCheck::Signature> Signatures,
bool IncludeSystem)
- : Signatures(Signatures), IncludeSystem(IncludeSystem) {}
+ : Signatures(decltype(this->Signatures)::withFlags(
+ unsigned(IncludeSystem), Signatures)) {}
ArrayRef<UseRangesCheck::Signature> getReplacementSignatures() const final {
return Signatures;
@@ -52,15 +54,16 @@ class BoostReplacer : public UseRangesCheck::Replacer {
std::optional<std::string>
getHeaderInclusion(const NamedDecl &OriginalName) const final {
auto [Path, HeaderName] = getBoostHeader(OriginalName);
- return ((IncludeSystem ? "<boost/" : "boost/") + Path +
+ return ((getIncludeSystem() ? "<boost/" : "boost/") + Path +
(Path.empty() ? "" : "/") + HeaderName +
- (IncludeSystem ? ".hpp>" : ".hpp"))
+ (getIncludeSystem() ? ".hpp>" : ".hpp"))
.str();
}
private:
- SmallVector<UseRangesCheck::Signature> Signatures;
- bool IncludeSystem;
+ llvm::SmallVectorWithFlags<UseRangesCheck::Signature> Signatures;
+ bool getIncludeSystem() const { return Signatures.getFlag(0); }
+ void setIncludeSystem(bool Value) { Signatures.setFlag(0, Value); }
};
/// Creates replaces where the header file lives in
diff --git a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
index f7c0024fc1fd1..0c7b608abde22 100644
--- a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp
@@ -14,6 +14,7 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -87,16 +88,22 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls,
AssertSideEffectCheck::AssertSideEffectCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
- CheckFunctionCalls(Options.get("CheckFunctionCalls", false)),
RawAssertList(Options.get("AssertMacros", "assert,NSAssert,NSCAssert")),
+ AssertMacros(decltype(this->AssertMacros)::withFlags([&] {
+ unsigned PackedFlags = 0;
+ PackedFlags |= unsigned(bool(Options.get("CheckFunctionCalls", false)));
+ return PackedFlags;
+ }())),
IgnoredFunctions(utils::options::parseListPair(
"__builtin_expect;", Options.get("IgnoredFunctions", ""))) {
- RawAssertList.split(AssertMacros, ",", -1, false);
+ for (StringRef Macro : llvm::split(RawAssertList, ','))
+ if (!Macro.empty())
+ AssertMacros.push_back(Macro);
}
// The options are explained in AssertSideEffectCheck.h.
void AssertSideEffectCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
- Options.store(Opts, "CheckFunctionCalls", CheckFunctionCalls);
+ Options.store(Opts, "CheckFunctionCalls", getCheckFunctionCalls());
Options.store(Opts, "AssertMacros", RawAssertList);
Options.store(Opts, "IgnoredFunctions",
utils::options::serializeStringList(IgnoredFunctions));
@@ -106,9 +113,9 @@ void AssertSideEffectCheck::registerMatchers(MatchFinder *Finder) {
const auto IgnoredFunctionsMatcher =
matchers::matchesAnyListedRegexName(IgnoredFunctions);
- const auto DescendantWithSideEffect =
- traverse(TK_AsIs, hasDescendant(expr(hasSideEffect(
- CheckFunctionCalls, IgnoredFunctionsMatcher))));
+ const auto DescendantWithSideEffect = traverse(
+ TK_AsIs, hasDescendant(expr(hasSideEffect(getCheckFunctionCalls(),
+ IgnoredFunctionsMatcher))));
const auto ConditionWithSideEffect = hasCondition(DescendantWithSideEffect);
Finder->addMatcher(
stmt(
diff --git a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.h b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.h
index b65e1a19e81ac..4b89445e98d41 100644
--- a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.h
@@ -11,6 +11,7 @@
#include "../ClangTidyCheck.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include <string>
@@ -37,10 +38,16 @@ class AssertSideEffectCheck : public ClangTidyCheck {
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
- const bool CheckFunctionCalls;
+ bool getCheckFunctionCalls() const { return AssertMacros.getFlag(0); }
const StringRef RawAssertList;
- SmallVector<StringRef, 5> AssertMacros;
+ llvm::SmallVectorWithFlags<StringRef, 5> AssertMacros;
const std::vector<StringRef> IgnoredFunctions;
+
+public:
+ AssertSideEffectCheck(const AssertSideEffectCheck &) = default;
+ AssertSideEffectCheck(AssertSideEffectCheck &&) = default;
+ AssertSideEffectCheck &operator=(const AssertSideEffectCheck &) = delete;
+ AssertSideEffectCheck &operator=(AssertSideEffectCheck &&) = delete;
};
} // namespace clang::tidy::bugprone
diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp
index 3cf0173aaa002..4702c0ec9eda0 100644
--- a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/FormatVariadic.h"
@@ -98,9 +99,10 @@ struct CallableInfo {
struct LambdaProperties {
CallableInfo Callable;
- SmallVector<BindArgument, 4> BindArguments;
+ llvm::SmallVectorWithFlags<BindArgument, 4> BindArguments;
StringRef BindNamespace;
- bool IsFixitSupported = false;
+ bool getIsFixitSupported() const { return BindArguments.getFlag(0); }
+ void setIsFixitSupported(bool Value) { BindArguments.setFlag(0, Value); }
};
} // end namespace
@@ -568,9 +570,9 @@ getLambdaProperties(const MatchFinder::MatchResult &Result) {
LP.Callable.CaptureInitializer = getSourceTextForExpr(Result, CalleeExpr);
}
- LP.BindArguments = buildBindArguments(Result, LP.Callable);
+ LP.BindArguments.assign(buildBindArguments(Result, LP.Callable));
- LP.IsFixitSupported = isFixitSupported(LP.Callable, LP.BindArguments);
+ LP.setIsFixitSupported(isFixitSupported(LP.Callable, LP.BindArguments));
return LP;
}
@@ -654,7 +656,7 @@ void AvoidBindCheck::check(const MatchFinder::MatchResult &Result) {
const auto Diag =
diag(MatchedDecl->getBeginLoc(),
formatv("prefer a lambda to {0}::bind", LP.BindNamespace).str());
- if (!LP.IsFixitSupported)
+ if (!LP.getIsFixitSupported())
return;
const auto *Ref = Result.Nodes.getNodeAs<Expr>("ref");
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
index 75bf2a7325900..1ea9b1e9abdcc 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -515,7 +515,7 @@ static bool canBeModified(ASTContext *Context, const Expr *E) {
/// Returns true when it can be guaranteed that the elements of the
/// container are not being modified.
-static bool usagesAreConst(ASTContext *Context, const UsageResult &Usages) {
+static bool usagesAreConst(ASTContext *Context, ArrayRef<Usage> Usages) {
return llvm::none_of(Usages, [&Context](const Usage &U) {
// Lambda captures are just redeclarations (VarDecl) of the same variable,
// not expressions. If we want to know if a variable that is captured by
@@ -530,7 +530,7 @@ static bool usagesAreConst(ASTContext *Context, const UsageResult &Usages) {
/// Returns true if the elements of the container are never accessed
/// by reference.
-static bool usagesReturnRValues(const UsageResult &Usages) {
+static bool usagesReturnRValues(ArrayRef<Usage> Usages) {
return llvm::all_of(Usages, [](const Usage &U) {
return !U.Expression || U.Expression->isPRValue();
});
@@ -663,7 +663,7 @@ void LoopConvertCheck::getAliasRange(SourceManager &SM, SourceRange &Range) {
/// applies them.
void LoopConvertCheck::doConversion(
ASTContext *Context, const VarDecl *IndexVar,
- const ValueDecl *MaybeContainer, const UsageResult &Usages,
+ const ValueDecl *MaybeContainer, ArrayRef<Usage> Usages,
const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit,
const ForStmt *Loop, RangeDescriptor Descriptor) {
std::string VarNameOrStructuredBinding;
@@ -868,7 +868,7 @@ StringRef LoopConvertCheck::getContainerString(ASTContext *Context,
void LoopConvertCheck::getArrayLoopQualifiers(ASTContext *Context,
const BoundNodes &Nodes,
const Expr *ContainerExpr,
- const UsageResult &Usages,
+ ArrayRef<Usage> Usages,
RangeDescriptor &Descriptor) {
// On arrays and pseudoarrays, we must figure out the qualifiers from the
// usages.
@@ -940,8 +940,8 @@ void LoopConvertCheck::getIteratorLoopQualifiers(ASTContext *Context,
/// Determines the parameters needed to build the range replacement.
void LoopConvertCheck::determineRangeDescriptor(
ASTContext *Context, const BoundNodes &Nodes, const ForStmt *Loop,
- LoopFixerKind FixerKind, const Expr *ContainerExpr,
- const UsageResult &Usages, RangeDescriptor &Descriptor) {
+ LoopFixerKind FixerKind, const Expr *ContainerExpr, ArrayRef<Usage> Usages,
+ RangeDescriptor &Descriptor) {
Descriptor.ContainerString =
std::string(getContainerString(Context, Loop, ContainerExpr));
Descriptor.NeedsReverseCall = (FixerKind == LFK_ReverseIterator);
@@ -1092,7 +1092,7 @@ void LoopConvertCheck::check(const MatchFinder::MatchResult &Result) {
// Find out which qualifiers we have to use in the loop range.
const TraversalKindScope RAII(*Context, TK_AsIs);
- const UsageResult &Usages = Finder.getUsages();
+ ArrayRef<Usage> Usages = Finder.getUsages();
determineRangeDescriptor(Context, Nodes, Loop, FixerKind, ContainerExpr,
Usages, Descriptor);
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h
index 958b4eb4ea2a5..cfe148334afb6 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.h
@@ -41,7 +41,7 @@ class LoopConvertCheck : public ClangTidyCheck {
void getAliasRange(SourceManager &SM, SourceRange &DeclRange);
void doConversion(ASTContext *Context, const VarDecl *IndexVar,
- const ValueDecl *MaybeContainer, const UsageResult &Usages,
+ const ValueDecl *MaybeContainer, ArrayRef<Usage> Usages,
const DeclStmt *AliasDecl, bool AliasUseRequired,
bool AliasFromForInit, const ForStmt *Loop,
RangeDescriptor Descriptor);
@@ -51,8 +51,7 @@ class LoopConvertCheck : public ClangTidyCheck {
void getArrayLoopQualifiers(ASTContext *Context,
const ast_matchers::BoundNodes &Nodes,
- const Expr *ContainerExpr,
- const UsageResult &Usages,
+ const Expr *ContainerExpr, ArrayRef<Usage> Usages,
RangeDescriptor &Descriptor);
void getIteratorLoopQualifiers(ASTContext *Context,
@@ -63,7 +62,7 @@ class LoopConvertCheck : public ClangTidyCheck {
const ast_matchers::BoundNodes &Nodes,
const ForStmt *Loop, LoopFixerKind FixerKind,
const Expr *ContainerExpr,
- const UsageResult &Usages,
+ ArrayRef<Usage> Usages,
RangeDescriptor &Descriptor);
bool isConvertible(ASTContext *Context, const ast_matchers::BoundNodes &Nodes,
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
index f173de2c52bc0..0ee44409c80ca 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp
@@ -450,8 +450,8 @@ ForLoopIndexUseVisitor::ForLoopIndexUseVisitor(ASTContext *Context,
bool ContainerNeedsDereference)
: Context(Context), IndexVar(IndexVar), EndVar(EndVar),
ContainerExpr(ContainerExpr), ArrayBoundExpr(ArrayBoundExpr),
- ContainerNeedsDereference(ContainerNeedsDereference),
-
+ Usages(decltype(this->Usages)::withFlags(
+ unsigned(ContainerNeedsDereference))),
ConfidenceLevel(Confidence::CL_Safe) {
if (ContainerExpr)
addComponent(ContainerExpr);
@@ -459,7 +459,7 @@ ForLoopIndexUseVisitor::ForLoopIndexUseVisitor(ASTContext *Context,
bool ForLoopIndexUseVisitor::findAndVerifyUsages(const Stmt *Body) {
TraverseStmt(const_cast<Stmt *>(Body));
- return OnlyUsedAsIndex && ContainerExpr;
+ return getOnlyUsedAsIndex() && ContainerExpr;
}
void ForLoopIndexUseVisitor::addComponents(const ComponentVector &Components) {
@@ -557,7 +557,7 @@ bool ForLoopIndexUseVisitor::TraverseMemberExpr(MemberExpr *Member) {
if (Obj && exprReferencesVariable(IndexVar, Obj)) {
// Member calls on the iterator with '.' are not allowed.
if (!Member->isArrow()) {
- OnlyUsedAsIndex = false;
+ setOnlyUsedAsIndex(false);
return true;
}
@@ -604,7 +604,7 @@ bool ForLoopIndexUseVisitor::TraverseCXXMemberCallExpr(
if (Ident && Ident->isStr("at") && MemberCall->getNumArgs() == 1 &&
isIndexInSubscriptExpr(Context, MemberCall->getArg(0), IndexVar,
Member->getBase(), ContainerExpr,
- ContainerNeedsDereference)) {
+ getContainerNeedsDereference())) {
addUsage(Usage(MemberCall));
return true;
}
@@ -649,7 +649,7 @@ bool ForLoopIndexUseVisitor::TraverseCXXOperatorCallExpr(
break;
if (isIndexInSubscriptExpr(Context, OpCall->getArg(1), IndexVar,
OpCall->getArg(0), ContainerExpr,
- ContainerNeedsDereference)) {
+ getContainerNeedsDereference())) {
addUsage(Usage(OpCall));
return true;
}
@@ -691,7 +691,7 @@ bool ForLoopIndexUseVisitor::TraverseArraySubscriptExpr(ArraySubscriptExpr *E) {
ArrayBoundExpr)) {
// If we have already discovered the array being indexed and this isn't it
// or this array doesn't match, mark this loop as unconvertible.
- OnlyUsedAsIndex = false;
+ setOnlyUsedAsIndex(false);
return VisitorBase::TraverseArraySubscriptExpr(E);
}
@@ -739,7 +739,7 @@ bool ForLoopIndexUseVisitor::VisitDeclRefExpr(DeclRefExpr *E) {
if (areSameVariable(IndexVar, TheDecl) ||
exprReferencesVariable(IndexVar, E) || areSameVariable(EndVar, TheDecl) ||
exprReferencesVariable(EndVar, E))
- OnlyUsedAsIndex = false;
+ setOnlyUsedAsIndex(false);
if (containsExpr(Context, &DependentExprs, E))
ConfidenceLevel.lowerTo(Confidence::CL_Risky);
return true;
@@ -798,13 +798,13 @@ bool ForLoopIndexUseVisitor::VisitDeclStmt(DeclStmt *S) {
if (CurrStmtParent) {
if (isa<IfStmt>(CurrStmtParent) || isa<WhileStmt>(CurrStmtParent) ||
isa<SwitchStmt>(CurrStmtParent)) {
- ReplaceWithAliasUse = true;
+ setReplaceWithAliasUse(true);
} else if (isa<ForStmt>(CurrStmtParent)) {
if (cast<ForStmt>(CurrStmtParent)->getConditionVariableDeclStmt() == S)
- ReplaceWithAliasUse = true;
+ setReplaceWithAliasUse(true);
else
// It's assumed S came the for loop's init clause.
- AliasFromForInit = true;
+ setAliasFromForInit(true);
}
}
}
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h
index 1415af6061783..f8ecd271712b7 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.h
@@ -15,6 +15,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <algorithm>
#include <memory>
#include <string>
@@ -304,7 +305,7 @@ class ForLoopIndexUseVisitor
void addComponents(const ComponentVector &Components);
/// Accessor for Usages.
- const UsageResult &getUsages() const { return Usages; }
+ ArrayRef<Usage> getUsages() const { return Usages; }
/// Adds the Usage if it was not added before.
void addUsage(const Usage &U);
@@ -325,12 +326,12 @@ class ForLoopIndexUseVisitor
/// simply be removed but rather replaced with a use of the alias variable.
/// For example, variables declared in the condition of an if, switch, or for
/// stmt.
- bool aliasUseRequired() const { return ReplaceWithAliasUse; }
+ bool aliasUseRequired() const { return getReplaceWithAliasUse(); }
/// Indicates if the alias declaration came from the init clause of a
/// nested for loop. SourceRanges provided by Clang for DeclStmts in this
/// case need to be adjusted.
- bool aliasFromForInit() const { return AliasFromForInit; }
+ bool aliasFromForInit() const { return getAliasFromForInit(); }
private:
/// Typedef used in CRTP functions.
@@ -365,14 +366,19 @@ class ForLoopIndexUseVisitor
const Expr *ContainerExpr;
/// The Expr which refers to the terminating condition for array-based loops.
const Expr *ArrayBoundExpr;
- bool ContainerNeedsDereference;
+ bool getContainerNeedsDereference() const { return Usages.getFlag(0); }
+ void setContainerNeedsDereference(bool Value) { Usages.setFlag(0, Value); }
// Output member variables:
/// A container which holds all usages of IndexVar as the index of
/// ArraySubscriptExpressions.
- UsageResult Usages;
+ llvm::SmallVectorWithFlagsFor<UsageResult, 4> Usages;
llvm::SmallSet<SourceLocation, 8> UsageLocations;
- bool OnlyUsedAsIndex = true;
+ bool getOnlyUsedAsIndex() const { return !Usages.getFlag(1); }
+ bool setOnlyUsedAsIndex(bool Value) {
+ Usages.setFlag(1, !Value);
+ return Value;
+ }
/// The DeclStmt for an alias to the container element.
const DeclStmt *AliasDecl = nullptr;
Confidence ConfidenceLevel;
@@ -392,9 +398,17 @@ class ForLoopIndexUseVisitor
const Stmt *CurrStmtParent = nullptr;
/// \see aliasUseRequired().
- bool ReplaceWithAliasUse = false;
+ bool getReplaceWithAliasUse() const { return Usages.getFlag(2); }
+ bool setReplaceWithAliasUse(bool Value) {
+ Usages.setFlag(2, Value);
+ return Value;
+ }
/// \see aliasFromForInit().
- bool AliasFromForInit = false;
+ bool getAliasFromForInit() const { return Usages.getFlag(3); }
+ bool setAliasFromForInit(bool Value) {
+ Usages.setFlag(3, Value);
+ return Value;
+ }
};
struct TUTrackingInfo {
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
index 42a16c8739808..b7f2ad7dc7462 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringExtras.h"
using namespace clang;
using namespace clang::ast_matchers;
@@ -92,7 +93,7 @@ void UseNullptrCheck::registerMatchers(MatchFinder *Finder) {
unless(hasAncestor(functionDecl(isDefaulted())))),
this);
- if (UseNullptrT)
+ if (getUseNullptrT())
Finder->addMatcher(typeLoc(loc(decltypeType(decltypeTypeNullptrLiteral())))
.bind("matchDecltypeNullptr"),
this);
@@ -509,13 +510,17 @@ class CastSequenceVisitor : public RecursiveASTVisitor<CastSequenceVisitor> {
UseNullptrCheck::UseNullptrCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
NullMacrosStr(Options.get("NullMacros", "NULL")),
+ NullMacros(decltype(this->NullMacros)::withFlags([&] {
+ unsigned PackedFlags = 0;
+ PackedFlags |= unsigned(bool(Options.get("UseNullptrT", true)));
+ return PackedFlags;
+ }())),
IgnoredTypes(utils::options::parseStringList(
Options.get("IgnoredTypes", DefaultIgnoredTypes))),
- UseNullptrT(Options.get("UseNullptrT", true)),
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
areDiagsSelfContained()) {
- NullMacrosStr.split(NullMacros, ",");
+ llvm::append_range(NullMacros, llvm::split(NullMacrosStr, ','));
}
void UseNullptrCheck::registerPPCallbacks(const SourceManager &SM,
@@ -529,7 +534,7 @@ void UseNullptrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IgnoredTypes",
utils::options::serializeStringList(IgnoredTypes));
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
- Options.store(Opts, "UseNullptrT", UseNullptrT);
+ Options.store(Opts, "UseNullptrT", getUseNullptrT());
}
void UseNullptrCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h
index 7f3eb6e4dd18b..ef8a3a3bf790d 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h
@@ -11,6 +11,7 @@
#include "../ClangTidyCheck.h"
#include "../utils/IncludeInserter.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang::tidy::modernize {
@@ -28,10 +29,16 @@ class UseNullptrCheck : public ClangTidyCheck {
private:
const StringRef NullMacrosStr;
- SmallVector<StringRef, 1> NullMacros;
+ llvm::SmallVectorWithFlags<StringRef, 1> NullMacros;
std::vector<StringRef> IgnoredTypes;
- const bool UseNullptrT;
+ bool getUseNullptrT() const { return NullMacros.getFlag(0); }
utils::IncludeInserter IncludeInserter;
+
+public:
+ UseNullptrCheck(const UseNullptrCheck &) = default;
+ UseNullptrCheck(UseNullptrCheck &&) = default;
+ UseNullptrCheck &operator=(const UseNullptrCheck &) = delete;
+ UseNullptrCheck &operator=(UseNullptrCheck &&) = delete;
};
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
index c0b11b7fc1afb..d38779d839cdb 100644
--- a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp
@@ -72,18 +72,33 @@ const char DefaultIgnoredFloatingPointValues[] = "1.0;100.0;";
MagicNumbersCheck::MagicNumbersCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
- IgnoreAllFloatingPointValues(
- Options.get("IgnoreAllFloatingPointValues", false)),
- IgnoreBitFieldsWidths(Options.get("IgnoreBitFieldsWidths", true)),
- IgnorePowersOf2IntegerValues(
- Options.get("IgnorePowersOf2IntegerValues", false)),
- IgnoreTypeAliases(Options.get("IgnoreTypeAliases", false)),
- IgnoreUserDefinedLiterals(
- Options.get("IgnoreUserDefinedLiterals", false)),
RawIgnoredIntegerValues(
Options.get("IgnoredIntegerValues", DefaultIgnoredIntegerValues)),
RawIgnoredFloatingPointValues(Options.get(
- "IgnoredFloatingPointValues", DefaultIgnoredFloatingPointValues)) {
+ "IgnoredFloatingPointValues", DefaultIgnoredFloatingPointValues)),
+ IgnoredFloatingPointValues(
+ decltype(this->IgnoredFloatingPointValues)::withFlags([&] {
+ unsigned PackedFlags = 0;
+ PackedFlags |= unsigned(
+ bool(Options.get("IgnoreAllFloatingPointValues", false)));
+ PackedFlags |=
+ (unsigned(bool(Options.get("IgnoreBitFieldsWidths", true)))
+ << 1);
+ PackedFlags |=
+ (unsigned(
+ bool(Options.get("IgnorePowersOf2IntegerValues", false)))
+ << 2);
+ PackedFlags |=
+ (unsigned(bool(Options.get("IgnoreTypeAliases", false))) << 3);
+ return PackedFlags;
+ }())),
+ IgnoredDoublePointValues(
+ decltype(this->IgnoredDoublePointValues)::withFlags([&] {
+ unsigned PackedFlags = 0;
+ PackedFlags |=
+ unsigned(bool(Options.get("IgnoreUserDefinedLiterals", false)));
+ return PackedFlags;
+ }())) {
// Process the set of ignored integer values.
const std::vector<StringRef> IgnoredIntegerValuesInput =
utils::options::parseStringList(RawIgnoredIntegerValues);
@@ -96,7 +111,7 @@ MagicNumbersCheck::MagicNumbersCheck(StringRef Name, ClangTidyContext *Context)
});
llvm::sort(IgnoredIntegerValues);
- if (!IgnoreAllFloatingPointValues) {
+ if (!getIgnoreAllFloatingPointValues()) {
// Process the set of ignored floating point values.
const std::vector<StringRef> IgnoredFloatingPointValuesInput =
utils::options::parseStringList(RawIgnoredFloatingPointValues);
@@ -124,12 +139,13 @@ MagicNumbersCheck::MagicNumbersCheck(StringRef Name, ClangTidyContext *Context)
void MagicNumbersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IgnoreAllFloatingPointValues",
- IgnoreAllFloatingPointValues);
- Options.store(Opts, "IgnoreBitFieldsWidths", IgnoreBitFieldsWidths);
+ getIgnoreAllFloatingPointValues());
+ Options.store(Opts, "IgnoreBitFieldsWidths", getIgnoreBitFieldsWidths());
Options.store(Opts, "IgnorePowersOf2IntegerValues",
- IgnorePowersOf2IntegerValues);
- Options.store(Opts, "IgnoreTypeAliases", IgnoreTypeAliases);
- Options.store(Opts, "IgnoreUserDefinedLiterals", IgnoreUserDefinedLiterals);
+ getIgnorePowersOf2IntegerValues());
+ Options.store(Opts, "IgnoreTypeAliases", getIgnoreTypeAliases());
+ Options.store(Opts, "IgnoreUserDefinedLiterals",
+ getIgnoreUserDefinedLiterals());
Options.store(Opts, "IgnoredIntegerValues", RawIgnoredIntegerValues);
Options.store(Opts, "IgnoredFloatingPointValues",
RawIgnoredFloatingPointValues);
@@ -137,7 +153,7 @@ void MagicNumbersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void MagicNumbersCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(integerLiteral().bind("integer"), this);
- if (!IgnoreAllFloatingPointValues)
+ if (!getIgnoreAllFloatingPointValues())
Finder->addMatcher(floatLiteral().bind("float"), this);
}
@@ -156,7 +172,7 @@ bool MagicNumbersCheck::isConstant(const MatchFinder::MatchResult &Result,
if (isUsedToInitializeAConstant(Result, Parent))
return true;
- if (IgnoreTypeAliases && isUsedToDefineATypeAlias(Result, Parent))
+ if (getIgnoreTypeAliases() && isUsedToDefineATypeAlias(Result, Parent))
return true;
// Ignore this instance, because this matches an
@@ -195,7 +211,7 @@ bool MagicNumbersCheck::isIgnoredValue(const IntegerLiteral *Literal) const {
if (Value == 0)
return true;
- if (IgnorePowersOf2IntegerValues && IntValue.isPowerOf2())
+ if (getIgnorePowersOf2IntegerValues() && IntValue.isPowerOf2())
return true;
return llvm::binary_search(IgnoredIntegerValues, Value);
@@ -235,7 +251,7 @@ bool MagicNumbersCheck::isSyntheticValue(const SourceManager *SourceManager,
bool MagicNumbersCheck::isBitFieldWidth(
const ast_matchers::MatchFinder::MatchResult &Result,
const IntegerLiteral &Literal) const {
- return IgnoreBitFieldsWidths &&
+ return getIgnoreBitFieldsWidths() &&
llvm::any_of(Result.Context->getParents(Literal),
[&Result](const DynTypedNode &Parent) {
return isUsedToDefineABitField(Result, Parent);
diff --git a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h
index ca64880c030cf..330a3ca47d989 100644
--- a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.h
@@ -11,6 +11,7 @@
#include "../ClangTidyCheck.h"
#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <llvm/ADT/APFloat.h>
#include <llvm/ADT/SmallVector.h>
@@ -75,7 +76,7 @@ class MagicNumbersCheck : public ClangTidyCheck {
if (isBitFieldWidth(Result, *MatchedLiteral))
return;
- if (IgnoreUserDefinedLiterals &&
+ if (getIgnoreUserDefinedLiterals() &&
isUserDefinedLiteral(Result, *MatchedLiteral))
return;
@@ -88,11 +89,21 @@ class MagicNumbersCheck : public ClangTidyCheck {
<< LiteralSourceText;
}
- const bool IgnoreAllFloatingPointValues;
- const bool IgnoreBitFieldsWidths;
- const bool IgnorePowersOf2IntegerValues;
- const bool IgnoreTypeAliases;
- const bool IgnoreUserDefinedLiterals;
+ bool getIgnoreAllFloatingPointValues() const {
+ return IgnoredFloatingPointValues.getFlag(0);
+ }
+ bool getIgnoreBitFieldsWidths() const {
+ return IgnoredFloatingPointValues.getFlag(1);
+ }
+ bool getIgnorePowersOf2IntegerValues() const {
+ return IgnoredFloatingPointValues.getFlag(2);
+ }
+ bool getIgnoreTypeAliases() const {
+ return IgnoredFloatingPointValues.getFlag(3);
+ }
+ bool getIgnoreUserDefinedLiterals() const {
+ return IgnoredDoublePointValues.getFlag(0);
+ }
const StringRef RawIgnoredIntegerValues;
const StringRef RawIgnoredFloatingPointValues;
@@ -103,10 +114,16 @@ class MagicNumbersCheck : public ClangTidyCheck {
SmallVector<int64_t, SensibleNumberOfMagicValueExceptions>
IgnoredIntegerValues;
- SmallVector<float, SensibleNumberOfMagicValueExceptions>
+ llvm::SmallVectorWithFlags<float, SensibleNumberOfMagicValueExceptions, 4>
IgnoredFloatingPointValues;
- SmallVector<double, SensibleNumberOfMagicValueExceptions>
+ llvm::SmallVectorWithFlags<double, SensibleNumberOfMagicValueExceptions>
IgnoredDoublePointValues;
+
+public:
+ MagicNumbersCheck(const MagicNumbersCheck &) = default;
+ MagicNumbersCheck(MagicNumbersCheck &&) = default;
+ MagicNumbersCheck &operator=(const MagicNumbersCheck &) = delete;
+ MagicNumbersCheck &operator=(MagicNumbersCheck &&) = delete;
};
} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
index 99f57374f3bda..5bcf749d17013 100644
--- a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
@@ -28,14 +28,18 @@ NamespaceCommentCheck::NamespaceCommentCheck(StringRef Name,
llvm::Regex::IgnoreCase),
ShortNamespaceLines(Options.get("ShortNamespaceLines", 1U)),
SpacesBeforeComments(Options.get("SpacesBeforeComments", 1U)),
- AllowOmittingNamespaceComments(
- Options.get("AllowOmittingNamespaceComments", false)) {}
+ Ends(decltype(this->Ends)::withFlags([&] {
+ unsigned PackedFlags = 0;
+ PackedFlags |= unsigned(
+ bool(Options.get("AllowOmittingNamespaceComments", false)));
+ return PackedFlags;
+ }())) {}
void NamespaceCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "ShortNamespaceLines", ShortNamespaceLines);
Options.store(Opts, "SpacesBeforeComments", SpacesBeforeComments);
Options.store(Opts, "AllowOmittingNamespaceComments",
- AllowOmittingNamespaceComments);
+ getAllowOmittingNamespaceComments());
}
void NamespaceCommentCheck::registerMatchers(MatchFinder *Finder) {
@@ -193,7 +197,7 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) {
: ("namespace '" + *NamespaceNameAsWritten + "'");
// If no namespace comment is allowed
- if (!HasComment && AllowOmittingNamespaceComments)
+ if (!HasComment && getAllowOmittingNamespaceComments())
return;
std::string Fix(SpacesBeforeComments, ' ');
diff --git a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h
index 68902428e9bab..328ff8184a112 100644
--- a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h
@@ -10,6 +10,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NAMESPACECOMMENTCHECK_H
#include "../ClangTidyCheck.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Regex.h"
namespace clang::tidy::readability {
@@ -34,8 +35,8 @@ class NamespaceCommentCheck : public ClangTidyCheck {
llvm::Regex NamespaceCommentPattern;
const unsigned ShortNamespaceLines;
const unsigned SpacesBeforeComments;
- const bool AllowOmittingNamespaceComments;
- SmallVector<SourceLocation, 4> Ends;
+ bool getAllowOmittingNamespaceComments() const { return Ends.getFlag(0); }
+ llvm::SmallVectorWithFlags<SourceLocation, 4> Ends;
};
} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
index 22237863ff041..4d82506c86298 100644
--- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
+++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
@@ -50,6 +50,7 @@
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
@@ -82,22 +83,35 @@ struct DriverArgs {
// Name of the driver program to execute or absolute path to it.
std::string Driver;
// Whether certain includes should be part of query.
- bool StandardIncludes = true;
- bool StandardCXXIncludes = true;
+ bool getStandardIncludes() const { return !Specs.getFlag(0); }
+ bool setStandardIncludes(bool Value) {
+ Specs.setFlag(0, !Value);
+ return Value;
+ }
+ bool getStandardCXXIncludes() const { return !Specs.getFlag(1); }
+ bool setStandardCXXIncludes(bool Value) {
+ Specs.setFlag(1, !Value);
+ return Value;
+ }
// Language to use while querying.
std::string Lang;
std::string Sysroot;
std::string ISysroot;
std::string Target;
std::string Stdlib;
- llvm::SmallVector<std::string> Specs;
+ llvm::SmallVectorWithFlags<
+ std::string,
+ llvm::CalculateSmallVectorDefaultInlinedElements<std::string>::value, 2>
+ Specs;
bool operator==(const DriverArgs &RHS) const {
- return std::tie(Driver, StandardIncludes, StandardCXXIncludes, Lang,
- Sysroot, ISysroot, Target, Stdlib, Specs) ==
- std::tie(RHS.Driver, RHS.StandardIncludes, RHS.StandardCXXIncludes,
- RHS.Lang, RHS.Sysroot, RHS.ISysroot, RHS.Target, RHS.Stdlib,
- RHS.Specs);
+ return getStandardIncludes() == RHS.getStandardIncludes() &&
+ getStandardCXXIncludes() == RHS.getStandardCXXIncludes() &&
+ llvm::ArrayRef<std::string>(Specs) ==
+ llvm::ArrayRef<std::string>(RHS.Specs) &&
+ std::tie(Driver, Lang, Sysroot, ISysroot, Target, Stdlib) ==
+ std::tie(RHS.Driver, RHS.Lang, RHS.Sysroot, RHS.ISysroot,
+ RHS.Target, RHS.Stdlib);
}
DriverArgs(const tooling::CompileCommand &Cmd, llvm::StringRef File) {
@@ -121,9 +135,9 @@ struct DriverArgs {
}
// Look for standard/builtin includes.
else if (Arg == "-nostdinc" || Arg == "--no-standard-includes")
- StandardIncludes = false;
+ setStandardIncludes(false);
else if (Arg == "-nostdinc++")
- StandardCXXIncludes = false;
+ setStandardCXXIncludes(false);
// Figure out sysroot
else if (Arg.consume_front("--sysroot")) {
if (Arg.consume_front("="))
@@ -187,9 +201,9 @@ struct DriverArgs {
// FIXME: Don't treat lang specially?
assert(!Lang.empty());
llvm::SmallVector<llvm::StringRef> Args = {"-x", Lang};
- if (!StandardIncludes)
+ if (!getStandardIncludes())
Args.push_back("-nostdinc");
- if (!StandardCXXIncludes)
+ if (!getStandardCXXIncludes())
Args.push_back("-nostdinc++");
if (!Sysroot.empty())
Args.append({"--sysroot", Sysroot});
@@ -218,8 +232,8 @@ template <> struct DenseMapInfo<DriverArgs> {
static unsigned getHashValue(const DriverArgs &Val) {
unsigned FixedFieldsHash = llvm::hash_value(std::tuple{
Val.Driver,
- Val.StandardIncludes,
- Val.StandardCXXIncludes,
+ Val.getStandardIncludes(),
+ Val.getStandardCXXIncludes(),
Val.Lang,
Val.Sysroot,
Val.ISysroot,
diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp
index 607b0382a2e98..01e6759e6a388 100644
--- a/clang-tools-extra/modularize/ModularizeUtilities.cpp
+++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp
@@ -335,7 +335,7 @@ bool ModularizeUtilities::collectModuleHeaders(const clang::Module &Mod) {
// Ignore explicit modules because they often have dependencies
// we can't know.
- if (Mod.IsExplicit)
+ if (Mod.getIsExplicit())
return true;
// Treat headers in umbrella directory as dependencies.
diff --git a/clang-tools-extra/modularize/PreprocessorTracker.cpp b/clang-tools-extra/modularize/PreprocessorTracker.cpp
index 6205b97a17176..e464433c56c68 100644
--- a/clang-tools-extra/modularize/PreprocessorTracker.cpp
+++ b/clang-tools-extra/modularize/PreprocessorTracker.cpp
@@ -249,6 +249,7 @@
#include "clang/Lex/MacroArgs.h"
#include "clang/Lex/PPCallbacks.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/raw_ostream.h"
@@ -769,10 +770,10 @@ ConditionalExpansionMapIter;
class PreprocessorTrackerImpl : public PreprocessorTracker {
public:
PreprocessorTrackerImpl(llvm::SmallVector<std::string, 32> &Headers,
- bool DoBlockCheckHeaderListOnly)
- : BlockCheckHeaderListOnly(DoBlockCheckHeaderListOnly),
- CurrentInclusionPathHandle(InclusionPathHandleInvalid),
- InNestedHeader(false) {
+ bool DoBlockCheckHeaderListOnly)
+ : HeaderList(decltype(HeaderList)::withFlags(
+ unsigned(DoBlockCheckHeaderListOnly))),
+ CurrentInclusionPathHandle(InclusionPathHandleInvalid) {
// Use canonical header path representation.
for (llvm::ArrayRef<std::string>::iterator I = Headers.begin(),
E = Headers.end();
@@ -804,7 +805,7 @@ class PreprocessorTrackerImpl : public PreprocessorTracker {
llvm::StringRef TargetPath) override {
// If it's not a header in the header list, ignore it with respect to
// the check.
- if (BlockCheckHeaderListOnly && !isHeaderListHeader(TargetPath))
+ if (getBlockCheckHeaderListOnly() && !isHeaderListHeader(TargetPath))
return;
HeaderHandle CurrentHeaderHandle = findHeaderHandle(DirectivePath);
StringHandle IncludeHeaderHandle = addString(TargetPath);
@@ -876,8 +877,8 @@ class PreprocessorTrackerImpl : public PreprocessorTracker {
if (H != getCurrentHeaderHandle())
pushHeaderHandle(H);
// Check for nested header.
- if (!InNestedHeader)
- InNestedHeader = !HeadersInThisCompile.insert(H).second;
+ if (!getInNestedHeader())
+ setInNestedHeader(!HeadersInThisCompile.insert(H).second);
}
// Handle exiting a header source file.
@@ -893,7 +894,7 @@ class PreprocessorTrackerImpl : public PreprocessorTracker {
popHeaderHandle();
} while ((TH != H) && (HeaderStack.size() != 0));
}
- InNestedHeader = false;
+ setInNestedHeader(false);
}
// Lookup/add string.
@@ -1022,7 +1023,7 @@ class PreprocessorTrackerImpl : public PreprocessorTracker {
llvm::StringRef MacroUnexpanded,
llvm::StringRef MacroExpanded,
InclusionPathHandle InclusionPathHandle) {
- if (InNestedHeader)
+ if (getInNestedHeader())
return;
StringHandle MacroName = addString(II->getName());
PPItemKey InstanceKey(PP, MacroName, H, InstanceLoc);
@@ -1071,7 +1072,7 @@ class PreprocessorTrackerImpl : public PreprocessorTracker {
llvm::StringRef ConditionUnexpanded,
InclusionPathHandle InclusionPathHandle) {
// Ignore header guards, assuming the header guard is the only conditional.
- if (InNestedHeader)
+ if (getInNestedHeader())
return;
StringHandle ConditionUnexpandedHandle(addString(ConditionUnexpanded));
PPItemKey InstanceKey(PP, ConditionUnexpandedHandle, H, InstanceLoc);
@@ -1222,9 +1223,10 @@ class PreprocessorTrackerImpl : public PreprocessorTracker {
}
private:
- llvm::SmallVector<std::string, 32> HeaderList;
+ llvm::SmallVectorWithFlags<std::string, 32, 2> HeaderList;
// Only do extern, namespace check for headers in HeaderList.
- bool BlockCheckHeaderListOnly;
+ bool getBlockCheckHeaderListOnly() const { return HeaderList.getFlag(0); }
+ void setBlockCheckHeaderListOnly(bool Value) { HeaderList.setFlag(0, Value); }
llvm::StringSet<> Strings;
std::vector<StringHandle> HeaderPaths;
std::vector<HeaderHandle> HeaderStack;
@@ -1234,7 +1236,8 @@ class PreprocessorTrackerImpl : public PreprocessorTracker {
std::vector<PPItemKey> IncludeDirectives;
MacroExpansionMap MacroExpansions;
ConditionalExpansionMap ConditionalExpansions;
- bool InNestedHeader;
+ bool getInNestedHeader() const { return HeaderList.getFlag(1); }
+ void setInNestedHeader(bool Value) { HeaderList.setFlag(1, Value); }
};
} // namespace
diff --git a/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp b/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp
index 082779358fbfb..471f2a289fd2a 100644
--- a/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp
+++ b/clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp
@@ -527,7 +527,7 @@ TEST(ClangMove, AddDependentNewHeader) {
Spec.OldCC = "foo.cc";
Spec.NewHeader = "new_foo.h";
Spec.NewCC = "new_foo.cc";
- Spec.OldDependOnNew = true;
+ Spec.setOldDependOnNew(true);
auto Results = runClangMoveOnCode(Spec, TestHeader, TestCode);
EXPECT_EQ(ExpectedOldHeader, Results[Spec.OldHeader]);
EXPECT_EQ(ExpectedNewHeader, Results[Spec.NewHeader]);
@@ -552,7 +552,7 @@ TEST(ClangMove, AddDependentOldHeader) {
Spec.OldCC = "foo.cc";
Spec.NewHeader = "new_foo.h";
Spec.NewCC = "new_foo.cc";
- Spec.NewDependOnOld = true;
+ Spec.setNewDependOnOld(true);
auto Results = runClangMoveOnCode(Spec, TestHeader, TestCode);
EXPECT_EQ(ExpectedNewHeader, Results[Spec.NewHeader]);
EXPECT_EQ(ExpectedOldHeader, Results[Spec.OldHeader]);
diff --git a/clang/include/clang/AST/ASTConcept.h b/clang/include/clang/AST/ASTConcept.h
index 839146f40445b..c5190b5c2a96d 100644
--- a/clang/include/clang/AST/ASTConcept.h
+++ b/clang/include/clang/AST/ASTConcept.h
@@ -22,6 +22,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <utility>
namespace clang {
@@ -48,7 +49,8 @@ class ConstraintSatisfaction : public llvm::FoldingSetNode {
// The template-like entity that 'owns' the constraint checked here (can be a
// constrained entity or a concept).
const NamedDecl *ConstraintOwner = nullptr;
- llvm::SmallVector<TemplateArgument, 4> TemplateArgs;
+ /// Flag bits 0 and 1 record satisfaction and the presence of errors.
+ llvm::SmallVectorWithFlags<TemplateArgument, 4, 2> TemplateArgs;
public:
@@ -58,8 +60,10 @@ class ConstraintSatisfaction : public llvm::FoldingSetNode {
ArrayRef<TemplateArgument> TemplateArgs)
: ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs) {}
- bool IsSatisfied = false;
- bool ContainsErrors = false;
+ bool isSatisfied() const { return TemplateArgs.getFlag(0); }
+ void setIsSatisfied(bool Value) { TemplateArgs.setFlag(0, Value); }
+ bool containsErrors() const { return TemplateArgs.getFlag(1); }
+ void setContainsErrors(bool Value) { TemplateArgs.setFlag(1, Value); }
/// \brief The substituted constraint expr, if the template arguments could be
/// substituted into them, or a diagnostic if substitution resulted in an
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 04cc2da25cecb..f0f3d2032009f 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -42,6 +42,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
@@ -245,7 +246,7 @@ struct QualTypeBoolInfo {
class ASTContext : public RefCountedBase<ASTContext> {
friend class NestedNameSpecifier;
- mutable SmallVector<Type *, 0> Types;
+ mutable llvm::SmallVectorWithFlags<Type *, 0, 3> Types;
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
mutable llvm::UniquingSet<ComplexType> ComplexTypes;
mutable llvm::UniquingSet<PointerType> PointerTypes{GeneralTypesLog2InitSize};
@@ -838,10 +839,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Address space map mangling must be used with language specific
/// address spaces (e.g. OpenCL/CUDA)
- bool AddrSpaceMapMangling;
+ bool getAddrSpaceMapMangling() const { return Types.getFlag(0); }
+ void setAddrSpaceMapMangling(bool Value) { Types.setFlag(0, Value); }
/// For performance, track whether any function effects are in use.
- mutable bool AnyFunctionEffects = false;
+ bool getAnyFunctionEffects() const { return Types.getFlag(1); }
+ bool setAnyFunctionEffects(bool Value) const {
+ Types.setFlag(1, Value);
+ return Value;
+ }
const TargetInfo *Target = nullptr;
const TargetInfo *AuxTarget = nullptr;
@@ -1048,7 +1054,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
RawCommentList Comments;
/// True if comments are already loaded from ExternalASTSource.
- mutable bool CommentsLoaded = false;
+ bool getCommentsLoaded() const { return Types.getFlag(2); }
+ void setCommentsLoaded(bool Value) const { Types.setFlag(2, Value); }
/// Key used to look up the raw comment attached to a declaration or macro.
using RawCommentLookupKey =
@@ -1520,7 +1527,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
ASTMutationListener *getASTMutationListener() const { return Listener; }
void PrintStats() const;
- const SmallVectorImpl<Type *>& getTypes() const { return Types; }
+ const llvm::SmallVectorWithFlagsImpl<Type *, 3> &getTypes() const {
+ return Types;
+ }
BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK,
const IdentifierInfo *II) const;
@@ -3402,10 +3411,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
uint64_t getTargetNullPointerValue(QualType QT) const;
bool addressSpaceMapManglingFor(LangAS AS) const {
- return AddrSpaceMapMangling || isTargetAddressSpace(AS);
+ return getAddrSpaceMapMangling() || isTargetAddressSpace(AS);
}
- bool hasAnyFunctionEffects() const { return AnyFunctionEffects; }
+ bool hasAnyFunctionEffects() const { return getAnyFunctionEffects(); }
// Merges two exception specifications, such that the resulting
// exception spec is the union of both. For example, if either
diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
index 18ce5a94ebef3..d097e1d5d274b 100644
--- a/clang/include/clang/AST/ExprConcepts.h
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -454,7 +454,7 @@ class NestedRequirement : public Requirement {
const ConstraintSatisfaction &Satisfaction)
: Requirement(RK_Nested, Constraint->isInstantiationDependent(),
Constraint->containsUnexpandedParameterPack(),
- Satisfaction.IsSatisfied),
+ Satisfaction.isSatisfied()),
Constraint(Constraint),
Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
diff --git a/clang/include/clang/AST/VTTBuilder.h b/clang/include/clang/AST/VTTBuilder.h
index 3c19e61a8701c..17830367a49cf 100644
--- a/clang/include/clang/AST/VTTBuilder.h
+++ b/clang/include/clang/AST/VTTBuilder.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <cstdint>
namespace clang {
@@ -82,7 +83,7 @@ class VTTBuilder {
using VTTComponentsVectorTy = SmallVector<VTTComponent, 64>;
/// The VTT components.
- VTTComponentsVectorTy VTTComponents;
+ llvm::SmallVectorWithFlagsFor<VTTComponentsVectorTy, 1> VTTComponents;
/// The AST record layout of the most derived class.
const ASTRecordLayout &MostDerivedClassLayout;
@@ -99,7 +100,8 @@ class VTTBuilder {
llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
/// Whether the VTT builder should generate LLVM IR for the VTT.
- bool GenerateDefinition;
+ bool getGenerateDefinition() const { return VTTComponents.getFlag(0); }
+ void setGenerateDefinition(bool Value) { VTTComponents.setFlag(0, Value); }
/// Add a vtable pointer to the VTT currently being built.
void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
@@ -138,9 +140,7 @@ class VTTBuilder {
bool GenerateDefinition);
// Returns a reference to the VTT components.
- const VTTComponentsVectorTy &getVTTComponents() const {
- return VTTComponents;
- }
+ ArrayRef<VTTComponent> getVTTComponents() const { return VTTComponents; }
// Returns a reference to the VTT vtables.
const VTTVTablesVectorTy &getVTTVTables() const {
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
index 16fe31a577fa1..b02033b5c086f 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>
@@ -402,9 +403,9 @@ class FactManager {
void addCapturedField(const FieldDecl *FD) { CapturedFields.insert(FD); }
bool isFieldCapturedByLambda(const FieldDecl *FD) const {
- return IsThisCapturedByLambda || CapturedFields.contains(FD);
+ return BlockToFacts.getFlag(0) || CapturedFields.contains(FD);
}
- void setThisCapturedByLambda() { IsThisCapturedByLambda = true; }
+ void setThisCapturedByLambda() { BlockToFacts.setFlag(0, true); }
private:
/// Classifies every origin as persistent or block-local. Called by
@@ -416,8 +417,9 @@ class FactManager {
FactID NextFactID{0};
LoanManager LoanMgr;
OriginManager OriginMgr;
- /// Facts for each CFG block, indexed by block ID.
- llvm::SmallVector<llvm::SmallVector<const Fact *>> BlockToFacts;
+ /// Facts for each CFG block, indexed by block ID. The flag tracks whether
+ /// any lambda captures the this pointer.
+ llvm::SmallVectorWithFlags<llvm::SmallVector<const Fact *>> BlockToFacts;
llvm::BumpPtrAllocator FactAllocator;
/// Bit vector indexed by origin ID. If set, the origin is referenced from
/// more than one basic block and must participate in join operations. If
@@ -431,9 +433,6 @@ class FactManager {
/// Set of field declarations that are explicitly or init-captured in any
/// lambda within the analyzed function.
llvm::DenseSet<const FieldDecl *> CapturedFields;
- /// Whether the 'this' pointer is captured by any lambda within the analyzed
- /// function. When true, any field of 'this' is considered captured.
- bool IsThisCapturedByLambda = false;
};
} // namespace clang::lifetimes::internal
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
index f5f84f27b5035..3e56fd4934844 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/FactsGenerator.h
@@ -22,6 +22,7 @@
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang::lifetimes::internal {
@@ -32,8 +33,9 @@ class FactsGenerator : public ConstStmtVisitor<FactsGenerator> {
FactsGenerator(FactManager &FactMgr, AnalysisDeclContext &AC,
const LifetimeSafetyOpts &LSOpts)
: FactMgr(FactMgr), AC(AC), LSOpts(LSOpts),
- IsCMode(!AC.getASTContext().getLangOpts().CPlusPlus &&
- !AC.getASTContext().getLangOpts().ObjC) {}
+ EscapesInCurrentBlock(decltype(this->EscapesInCurrentBlock)::withFlags(
+ unsigned(bool(!AC.getASTContext().getLangOpts().CPlusPlus &&
+ !AC.getASTContext().getLangOpts().ObjC)))) {}
void run();
@@ -174,9 +176,10 @@ class FactsGenerator : public ConstStmtVisitor<FactsGenerator> {
// Collect origins that escape the function in this block (OriginEscapesFact),
// appended at the end of CurrentBlockFacts to ensure they appear after
// ExpireFact entries.
- llvm::SmallVector<Fact *> EscapesInCurrentBlock;
+ llvm::SmallVectorWithFlags<Fact *> EscapesInCurrentBlock;
const CFGBlock *CurrentBlock;
- bool IsCMode = false;
+ bool getIsCMode() const { return EscapesInCurrentBlock.getFlag(0); }
+ void setIsCMode(bool Value) { EscapesInCurrentBlock.setFlag(0, Value); }
};
} // namespace clang::lifetimes::internal
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index f8bd097733529..922fc858309aa 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4961,9 +4961,9 @@ def OMPDeclareVariant : InheritableAttr {
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
const;
static StringRef getInteropTypeString(const OMPInteropInfo *I) {
- if (I->IsTarget && I->IsTargetSync)
+ if (I->isTarget() && I->isTargetSync())
return "target,targetsync";
- if (I->IsTarget)
+ if (I->isTarget())
return "target";
return "targetsync";
}
diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h
index 4d304b8f006b6..4adc8b5f707bd 100644
--- a/clang/include/clang/Basic/Module.h
+++ b/clang/include/clang/Basic/Module.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -498,7 +499,7 @@ class alignas(8) Module {
// The begin index for a HeaderKind also acts the end index of HeaderKind - 1.
// The extra element at the end acts as the end index of the last HeaderKind.
unsigned HeaderKindBeginIndex[NumHeaderKinds + 1] = {};
- SmallVector<Header, 2> HeadersStorage;
+ llvm::SmallVectorWithFlags<Header, 2, 4> HeadersStorage;
public:
ArrayRef<Header> getAllHeaders() const { return HeadersStorage; }
@@ -552,7 +553,7 @@ class alignas(8) Module {
///
/// If any of these requirements are not available, the \c IsAvailable bit
/// will be false to indicate that this (sub)module is not available.
- SmallVector<Requirement, 2> Requirements;
+ llvm::SmallVectorWithFlags<Requirement, 2, 4> Requirements;
/// A module with the same name that shadows this module.
Module *ShadowingModule = nullptr;
@@ -560,86 +561,129 @@ class alignas(8) Module {
/// Whether this module has declared itself unimportable, either because
/// it's missing a requirement from \p Requirements or because it's been
/// shadowed by another module.
- LLVM_PREFERRED_TYPE(bool)
- unsigned IsUnimportable : 1;
+ unsigned getIsUnimportable() const { return Requirements.getFlag(0); }
+ void setIsUnimportable(unsigned Value) {
+ Requirements.setFlag(0, (Value & 1));
+ }
/// Whether we tried and failed to load a module file for this module.
- LLVM_PREFERRED_TYPE(bool)
- unsigned HasIncompatibleModuleFile : 1;
+ unsigned getHasIncompatibleModuleFile() const {
+ return Requirements.getFlag(1);
+ }
+ void setHasIncompatibleModuleFile(unsigned Value) {
+ Requirements.setFlag(1, (Value & 1));
+ }
/// Whether this module is available in the current translation unit.
///
/// If the module is missing headers or does not meet all requirements then
/// this bit will be 0.
- LLVM_PREFERRED_TYPE(bool)
- unsigned IsAvailable : 1;
+ unsigned getIsAvailable() const { return Requirements.getFlag(2); }
+ void setIsAvailable(unsigned Value) { Requirements.setFlag(2, (Value & 1)); }
/// Whether this module was loaded from a module file.
- LLVM_PREFERRED_TYPE(bool)
- unsigned IsFromModuleFile : 1;
+ unsigned getIsFromModuleFile() const { return Requirements.getFlag(3); }
+ void setIsFromModuleFile(unsigned Value) {
+ Requirements.setFlag(3, (Value & 1));
+ }
/// Whether this is a framework module.
- LLVM_PREFERRED_TYPE(bool)
- unsigned IsFramework : 1;
+ unsigned getIsFramework() const { return HeadersStorage.getFlag(0); }
+ void setIsFramework(unsigned Value) {
+ HeadersStorage.setFlag(0, (Value & 1));
+ }
/// Whether this is an explicit submodule.
- LLVM_PREFERRED_TYPE(bool)
- unsigned IsExplicit : 1;
+ unsigned getIsExplicit() const { return HeadersStorage.getFlag(1); }
+ void setIsExplicit(unsigned Value) { HeadersStorage.setFlag(1, (Value & 1)); }
/// Whether this is a "system" module (which assumes that all
/// headers in it are system headers).
- LLVM_PREFERRED_TYPE(bool)
- unsigned IsSystem : 1;
+ unsigned getIsSystem() const { return HeadersStorage.getFlag(2); }
+ unsigned setIsSystem(unsigned Value) {
+ HeadersStorage.setFlag(2, (Value & 1));
+ return (Value & 1);
+ }
/// Whether this is an 'extern "C"' module (which implicitly puts all
/// headers in it within an 'extern "C"' block, and allows the module to be
/// imported within such a block).
- LLVM_PREFERRED_TYPE(bool)
- unsigned IsExternC : 1;
+ unsigned getIsExternC() const { return HeadersStorage.getFlag(3); }
+ unsigned setIsExternC(unsigned Value) {
+ HeadersStorage.setFlag(3, (Value & 1));
+ return (Value & 1);
+ }
/// Whether this is an inferred submodule (module * { ... }).
- LLVM_PREFERRED_TYPE(bool)
- unsigned IsInferred : 1;
+ unsigned getIsInferred() const { return LinkLibraries.getFlag(0); }
+ void setIsInferred(unsigned Value) { LinkLibraries.setFlag(0, (Value & 1)); }
/// Whether we should infer submodules for this module based on
/// the headers.
///
/// Submodules can only be inferred for modules with an umbrella header.
- LLVM_PREFERRED_TYPE(bool)
- unsigned InferSubmodules : 1;
+ unsigned getInferSubmodules() const { return LinkLibraries.getFlag(1); }
+ void setInferSubmodules(unsigned Value) {
+ LinkLibraries.setFlag(1, (Value & 1));
+ }
/// Whether, when inferring submodules, the inferred submodules
/// should be explicit.
- LLVM_PREFERRED_TYPE(bool)
- unsigned InferExplicitSubmodules : 1;
+ unsigned getInferExplicitSubmodules() const {
+ return LinkLibraries.getFlag(2);
+ }
+ void setInferExplicitSubmodules(unsigned Value) {
+ LinkLibraries.setFlag(2, (Value & 1));
+ }
/// Whether, when inferring submodules, the inferr submodules should
/// export all modules they import (e.g., the equivalent of "export *").
- LLVM_PREFERRED_TYPE(bool)
- unsigned InferExportWildcard : 1;
+ unsigned getInferExportWildcard() const { return LinkLibraries.getFlag(3); }
+ unsigned setInferExportWildcard(unsigned Value) {
+ LinkLibraries.setFlag(3, (Value & 1));
+ return (Value & 1);
+ }
/// Whether the set of configuration macros is exhaustive.
///
/// When the set of configuration macros is exhaustive, meaning
/// that no identifier not in this list should affect how the module is
/// built.
- LLVM_PREFERRED_TYPE(bool)
- unsigned ConfigMacrosExhaustive : 1;
+ unsigned getConfigMacrosExhaustive() const {
+ return UnresolvedDirectUses.getFlag(0);
+ }
+ void setConfigMacrosExhaustive(unsigned Value) {
+ UnresolvedDirectUses.setFlag(0, (Value & 1));
+ }
/// Whether files in this module can only include non-modular headers
/// and headers from used modules.
- LLVM_PREFERRED_TYPE(bool)
- unsigned NoUndeclaredIncludes : 1;
+ unsigned getNoUndeclaredIncludes() const {
+ return UnresolvedDirectUses.getFlag(1);
+ }
+ unsigned setNoUndeclaredIncludes(unsigned Value) {
+ UnresolvedDirectUses.setFlag(1, (Value & 1));
+ return (Value & 1);
+ }
/// Whether this module came from a "private" module map, found next
/// to a regular (public) module map.
- LLVM_PREFERRED_TYPE(bool)
- unsigned ModuleMapIsPrivate : 1;
+ unsigned getModuleMapIsPrivate() const {
+ return UnresolvedDirectUses.getFlag(2);
+ }
+ void setModuleMapIsPrivate(unsigned Value) {
+ UnresolvedDirectUses.setFlag(2, (Value & 1));
+ }
/// Whether this C++20 named modules doesn't need an initializer.
/// This is only meaningful for C++20 modules.
- LLVM_PREFERRED_TYPE(bool)
- unsigned NamedModuleHasInit : 1;
+ unsigned getNamedModuleHasInit() const {
+ return UnresolvedDirectUses.getFlag(3);
+ }
+ unsigned setNamedModuleHasInit(unsigned Value) {
+ UnresolvedDirectUses.setFlag(3, (Value & 1));
+ return (Value & 1);
+ }
/// Describes the visibility of the various names within a
/// particular module.
@@ -680,22 +724,26 @@ class alignas(8) Module {
SourceLocation ExportLoc;
/// The name of the module.
- ModuleId Id;
+ llvm::SmallVectorWithFlagsFor<ModuleId, 1> Id;
/// Whether this export declaration ends in a wildcard, indicating
/// that all of its submodules should be exported (rather than the named
/// module itself).
- bool Wildcard;
+ bool getWildcard() const { return Id.getFlag(0); }
+ void setWildcard(bool Value) { Id.setFlag(0, Value); }
+
+ UnresolvedExportDecl(SourceLocation ExportLoc, ModuleId Id, bool Wildcard)
+ : ExportLoc(ExportLoc), Id(unsigned(Wildcard), std::move(Id)) {}
};
/// The set of export declarations that have yet to be resolved.
SmallVector<UnresolvedExportDecl, 2> UnresolvedExports;
/// The directly used modules.
- SmallVector<Module *, 2> DirectUses;
+ llvm::SmallVectorWithFlags<Module *, 2> DirectUses;
/// The set of use declarations that have yet to be resolved.
- SmallVector<ModuleId, 2> UnresolvedDirectUses;
+ llvm::SmallVectorWithFlags<ModuleId, 2, 4> UnresolvedDirectUses;
/// When \c NoUndeclaredIncludes is true, the set of modules this module tried
/// to import but didn't because they are not direct uses.
@@ -720,11 +768,15 @@ class alignas(8) Module {
/// The set of libraries or frameworks to link against when
/// an entity from this module is used.
- llvm::SmallVector<LinkLibrary, 2> LinkLibraries;
+ llvm::SmallVectorWithFlags<LinkLibrary, 2, 4> LinkLibraries;
/// Autolinking uses the framework name for linking purposes
/// when this is false and the export_as name otherwise.
- bool UseExportAsModuleLinkName = false;
+ bool getUseExportAsModuleLinkName() const { return DirectUses.getFlag(0); }
+ bool setUseExportAsModuleLinkName(bool Value) {
+ DirectUses.setFlag(0, Value);
+ return Value;
+ }
/// The set of "configuration macros", which are macros that
/// (intentionally) change how this module is built.
@@ -763,7 +815,7 @@ class alignas(8) Module {
~Module();
/// Determine whether this module has been declared unimportable.
- bool isUnimportable() const { return IsUnimportable; }
+ bool isUnimportable() const { return getIsUnimportable(); }
/// Determine whether this module has been declared unimportable.
///
@@ -786,7 +838,7 @@ class alignas(8) Module {
/// Determine whether this module is available for use within the
/// current translation unit.
- bool isAvailable() const { return IsAvailable; }
+ bool isAvailable() const { return getIsAvailable(); }
/// Determine whether this module is available for use within the
/// current translation unit.
@@ -827,7 +879,7 @@ class alignas(8) Module {
/// of a framework module.
bool isPartOfFramework() const {
for (const Module *Mod = this; Mod; Mod = Mod->Parent)
- if (Mod->IsFramework)
+ if (Mod->getIsFramework())
return true;
return false;
@@ -836,7 +888,7 @@ class alignas(8) Module {
/// Determine whether this module is a subframework of another
/// framework.
bool isSubFramework() const {
- return IsFramework && Parent && Parent->isPartOfFramework();
+ return getIsFramework() && Parent && Parent->isPartOfFramework();
}
/// Set the parent of this module. This should only be used if the parent
@@ -902,7 +954,7 @@ class alignas(8) Module {
return Kind == ModuleInterfaceUnit || Kind == ModulePartitionInterface;
}
- bool isNamedModuleInterfaceHasInit() const { return NamedModuleHasInit; }
+ bool isNamedModuleInterfaceHasInit() const { return getNamedModuleHasInit(); }
/// Get the primary module interface name from a partition.
StringRef getPrimaryModuleInterfaceName() const {
diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index 36c388668a455..68041da8263a9 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -16,6 +16,7 @@
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -318,11 +319,15 @@ struct OMPInteropPref final {
};
struct OMPInteropInfo final {
OMPInteropInfo(bool IsTarget = false, bool IsTargetSync = false)
- : IsTarget(IsTarget), IsTargetSync(IsTargetSync) {}
- bool IsTarget;
- bool IsTargetSync;
- bool HasPreferAttrs = false;
- llvm::SmallVector<OMPInteropPref, 4> Prefs;
+ : Prefs(decltype(this->Prefs)::withFlags(
+ unsigned(IsTarget) | (unsigned(IsTargetSync) << 1))) {}
+ bool isTarget() const { return Prefs.getFlag(0); }
+ void setIsTarget(bool Value) { Prefs.setFlag(0, Value); }
+ bool isTargetSync() const { return Prefs.getFlag(1); }
+ void setIsTargetSync(bool Value) { Prefs.setFlag(1, Value); }
+ bool hasPreferAttrs() const { return Prefs.getFlag(2); }
+ void setPreferAttrs(bool Value) { Prefs.setFlag(2, Value); }
+ llvm::SmallVectorWithFlags<OMPInteropPref, 4, 3> Prefs;
};
OpenMPDefaultClauseVariableCategory
diff --git a/clang/include/clang/Basic/Sarif.h b/clang/include/clang/Basic/Sarif.h
index 7651d2ac7a768..42ae11cac3a6f 100644
--- a/clang/include/clang/Basic/Sarif.h
+++ b/clang/include/clang/Basic/Sarif.h
@@ -35,6 +35,7 @@
#include "clang/Basic/Version.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/JSON.h"
@@ -519,7 +520,8 @@ class SarifDocumentWriter {
/// A closed document is one on which a new runs must be created.
/// This could be a document that is freshly created, or has recently
/// finished writing to a previous run.
- bool Closed = true;
+ bool getClosed() const { return !CurrentRules.getFlag(0); }
+ void setClosed(bool Value) { CurrentRules.setFlag(0, !Value); }
/// A sequence of SARIF runs.
/// Each run object describes a single run of an analysis tool and contains
@@ -536,7 +538,7 @@ class SarifDocumentWriter {
/// also known as "reportingDescriptor" objects in SARIF.
///
/// Reference: <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317556">rules property</a>
- llvm::SmallVector<SarifRule, 32> CurrentRules;
+ llvm::SmallVectorWithFlags<SarifRule, 32> CurrentRules;
/// The list of artifacts that have been encountered on the most recent active
/// run. An artifact is defined in SARIF as a sequence of bytes addressable
diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
index 1939d1aa4915e..5d2e710fa0bc8 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -46,6 +46,7 @@
#include "llvm/ADT/PagedVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
@@ -678,16 +679,31 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// True if the ContentCache for files that are overridden by other
/// files, should report the original file name. Defaults to true.
- bool OverridenFilesKeepOriginalName = true;
+ bool getOverridenFilesKeepOriginalNameFlag() const {
+ return !StoredModuleBuildStack.getFlag(0);
+ }
+ void setOverridenFilesKeepOriginalNameFlag(bool Value) {
+ StoredModuleBuildStack.setFlag(0, !Value);
+ }
/// True if non-system source files should be treated as volatile
/// (likely to change while trying to use them). Defaults to false.
- bool UserFilesAreVolatile;
+ bool getUserFilesAreVolatile() const {
+ return StoredModuleBuildStack.getFlag(1);
+ }
+ void setUserFilesAreVolatile(bool Value) {
+ StoredModuleBuildStack.setFlag(1, Value);
+ }
/// True if all files read during this compilation should be treated
/// as transient (may not be present in later compilations using a module
/// file created from this compilation). Defaults to false.
- bool FilesAreTransient = false;
+ bool getFilesAreTransient() const {
+ return StoredModuleBuildStack.getFlag(2);
+ }
+ void setFilesAreTransient(bool Value) {
+ StoredModuleBuildStack.setFlag(2, Value);
+ }
struct OverriddenFilesInfoTy {
/// Files that have been overridden with the contents from another
@@ -844,7 +860,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// There is no way to set this value from the command line. If we ever need
/// to do so (e.g., if on-demand module construction moves out-of-process),
/// we can add a cc1-level option to do so.
- SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack;
+ llvm::SmallVectorWithFlags<std::pair<std::string, FullSourceLoc>, 2, 3>
+ StoredModuleBuildStack;
public:
SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr,
@@ -867,12 +884,12 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// for contents of files that were overridden by other files. Defaults to
/// true.
void setOverridenFilesKeepOriginalName(bool value) {
- OverridenFilesKeepOriginalName = value;
+ setOverridenFilesKeepOriginalNameFlag(value);
}
/// True if non-system source files should be treated as volatile
/// (likely to change while trying to use them).
- bool userFilesAreVolatile() const { return UserFilesAreVolatile; }
+ bool userFilesAreVolatile() const { return getUserFilesAreVolatile(); }
/// Retrieve the module build stack.
ModuleBuildStack getModuleBuildStack() const {
@@ -1046,7 +1063,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// Specify that all files that are read during this compilation are
/// transient.
void setAllFilesAreTransient(bool Transient) {
- FilesAreTransient = Transient;
+ setFilesAreTransient(Transient);
}
//===--------------------------------------------------------------------===//
diff --git a/clang/include/clang/CodeGen/CodeGenAction.h b/clang/include/clang/CodeGen/CodeGenAction.h
index 84fa4549d5033..c222f35509891 100644
--- a/clang/include/clang/CodeGen/CodeGenAction.h
+++ b/clang/include/clang/CodeGen/CodeGenAction.h
@@ -11,6 +11,7 @@
#include "clang/CodeGen/ModuleLinker.h"
#include "clang/Frontend/FrontendAction.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <memory>
namespace llvm {
@@ -28,9 +29,10 @@ class CodeGenAction : public ASTFrontendAction {
std::unique_ptr<llvm::Module> TheModule;
/// Bitcode modules to link in to our module.
- SmallVector<LinkModule, 4> LinkModules;
+ llvm::SmallVectorWithFlags<LinkModule, 4> LinkModules;
llvm::LLVMContext *VMContext;
- bool OwnsVMContext;
+ bool getOwnsVMContext() const { return LinkModules.getFlag(0); }
+ void setOwnsVMContext(bool Value) { LinkModules.setFlag(0, Value); }
std::unique_ptr<llvm::Module> loadModule(llvm::MemoryBufferRef MBRef);
diff --git a/clang/include/clang/CodeGen/ConstantInitBuilder.h b/clang/include/clang/CodeGen/ConstantInitBuilder.h
index 70a6ac323ccec..8697afa978aee 100644
--- a/clang/include/clang/CodeGen/ConstantInitBuilder.h
+++ b/clang/include/clang/CodeGen/ConstantInitBuilder.h
@@ -15,12 +15,13 @@
#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
#define LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
+#include "clang/AST/CharUnits.h"
+#include "clang/CodeGen/ConstantInitFuture.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/GlobalValue.h"
-#include "clang/AST/CharUnits.h"
-#include "clang/CodeGen/ConstantInitFuture.h"
#include <optional>
#include <vector>
@@ -60,9 +61,10 @@ class ConstantInitBuilderBase {
SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {}
};
CodeGenModule &CGM;
- llvm::SmallVector<llvm::Constant*, 16> Buffer;
+ llvm::SmallVectorWithFlags<llvm::Constant *, 16> Buffer;
std::vector<SelfReference> SelfReferences;
- bool Frozen = false;
+ bool getFrozen() const { return Buffer.getFlag(0); }
+ void setFrozen(bool Value) { Buffer.setFlag(0, Value); }
friend class ConstantInitFuture;
friend class ConstantAggregateBuilderBase;
@@ -108,11 +110,11 @@ class ConstantAggregateBuilderBase {
bool Packed = false;
mutable CharUnits CachedOffsetFromGlobal;
- llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
+ llvm::SmallVectorWithFlagsImpl<llvm::Constant *> &getBuffer() {
return Builder.Buffer;
}
- const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
+ const llvm::SmallVectorWithFlagsImpl<llvm::Constant *> &getBuffer() const {
return Builder.Buffer;
}
@@ -123,8 +125,9 @@ class ConstantAggregateBuilderBase {
assert(!parent->Frozen && "parent already has child builder active");
parent->Frozen = true;
} else {
- assert(!builder.Frozen && "builder already has child builder active");
- builder.Frozen = true;
+ assert(!builder.getFrozen() &&
+ "builder already has child builder active");
+ builder.setFrozen(true);
}
}
@@ -141,9 +144,9 @@ class ConstantAggregateBuilderBase {
"parent not frozen while child builder active");
Parent->Frozen = false;
} else {
- assert(Builder.Frozen &&
+ assert(Builder.getFrozen() &&
"builder not frozen while child builder active");
- Builder.Frozen = false;
+ Builder.setFrozen(false);
}
}
diff --git a/clang/include/clang/CodeGen/SwiftCallingConv.h b/clang/include/clang/CodeGen/SwiftCallingConv.h
index d7a0c84699ab0..540749a67d682 100644
--- a/clang/include/clang/CodeGen/SwiftCallingConv.h
+++ b/clang/include/clang/CodeGen/SwiftCallingConv.h
@@ -17,6 +17,7 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Type.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
@@ -50,8 +51,9 @@ class SwiftAggLowering {
return End - Begin;
}
};
- SmallVector<StorageEntry, 4> Entries;
- bool Finished = false;
+ llvm::SmallVectorWithFlags<StorageEntry, 4> Entries;
+ bool getFinished() const { return Entries.getFlag(0); }
+ void setFinished(bool Value) { Entries.setFlag(0, Value); }
public:
SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {}
@@ -71,7 +73,7 @@ class SwiftAggLowering {
/// Does this lowering require passing any data?
bool empty() const {
- assert(Finished && "didn't finish lowering before calling empty()");
+ assert(getFinished() && "didn't finish lowering before calling empty()");
return Entries.empty();
}
diff --git a/clang/include/clang/DependencyScanning/DependencyGraph.h b/clang/include/clang/DependencyScanning/DependencyGraph.h
index f35786418fc60..23df4e4e0f499 100644
--- a/clang/include/clang/DependencyScanning/DependencyGraph.h
+++ b/clang/include/clang/DependencyScanning/DependencyGraph.h
@@ -14,6 +14,7 @@
#include "clang/Frontend/CompilerInvocation.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <string>
#include <variant>
@@ -80,7 +81,8 @@ struct ModuleDeps {
ModuleID ID;
/// Whether this is a "system" module.
- bool IsSystem;
+ bool getIsSystem() const { return LinkLibraries.getFlag(0); }
+ void setIsSystem(bool Value) { LinkLibraries.setFlag(0, Value); }
/// Whether this module is fully composed of file & module inputs from
/// locations likely to stay the same across the active development and build
@@ -88,10 +90,15 @@ struct ModuleDeps {
///
/// External paths, as opposed to virtual file paths, are always used
/// for computing this value.
- bool IsInStableDirectories;
+ bool getIsInStableDirectories() const { return LinkLibraries.getFlag(1); }
+ bool setIsInStableDirectories(bool Value) {
+ LinkLibraries.setFlag(1, Value);
+ return Value;
+ }
/// Whether current working directory is ignored.
- bool IgnoreCWD;
+ bool getIgnoreCWD() const { return LinkLibraries.getFlag(2); }
+ void setIgnoreCWD(bool Value) { LinkLibraries.setFlag(2, Value); }
/// The path to the modulemap file which defines this module.
///
@@ -126,7 +133,7 @@ struct ModuleDeps {
/// The set of libraries or frameworks to link against when
/// an entity from this module is used.
- llvm::SmallVector<Module::LinkLibrary, 2> LinkLibraries;
+ llvm::SmallVectorWithFlags<Module::LinkLibrary, 2, 3> LinkLibraries;
/// Invokes \c Cb for all file dependencies of this module. Each provided
/// \c StringRef is only valid within the individual callback invocation.
diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h
index b4b91e7010941..0b85f123b0aa9 100644
--- a/clang/include/clang/Driver/Action.h
+++ b/clang/include/clang/Driver/Action.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include <string>
@@ -109,13 +110,18 @@ class Action {
/// The output type of this action.
types::ID Type;
- ActionList Inputs;
+ llvm::SmallVectorWithFlagsFor<ActionList, 1> Inputs;
/// Flag that is set to true if this action can be collapsed with others
/// actions that depend on it. This is true by default and set to false when
/// the action is used by two different tool chains, which is enabled by the
/// offloading support implementation.
- bool CanBeCollapsedWithNextDependentAction = true;
+ bool getCanBeCollapsedWithNextDependentAction() const {
+ return !Inputs.getFlag(0);
+ }
+ void setCanBeCollapsedWithNextDependentAction(bool Value) {
+ Inputs.setFlag(0, !Value);
+ }
protected:
///
@@ -142,7 +148,7 @@ class Action {
Action(ActionClass Kind, Action *Input)
: Action(Kind, ActionList({Input}), Input->getType()) {}
Action(ActionClass Kind, const ActionList &Inputs, types::ID Type)
- : Kind(Kind), Type(Type), Inputs(Inputs) {}
+ : Kind(Kind), Type(Type), Inputs(Inputs.begin(), Inputs.end()) {}
public:
virtual ~Action();
@@ -152,8 +158,10 @@ class Action {
ActionClass getKind() const { return Kind; }
types::ID getType() const { return Type; }
- ActionList &getInputs() { return Inputs; }
- const ActionList &getInputs() const { return Inputs; }
+ llvm::SmallVectorWithFlagsFor<ActionList, 1> &getInputs() { return Inputs; }
+ const llvm::SmallVectorWithFlagsFor<ActionList, 1> &getInputs() const {
+ return Inputs;
+ }
size_type size() const { return Inputs.size(); }
@@ -168,12 +176,12 @@ class Action {
/// Mark this action as not legal to collapse.
void setCannotBeCollapsedWithNextDependentAction() {
- CanBeCollapsedWithNextDependentAction = false;
+ setCanBeCollapsedWithNextDependentAction(false);
}
/// Return true if this function can be collapsed with others.
bool isCollapsingWithNextDependentActionLegal() const {
- return CanBeCollapsedWithNextDependentAction;
+ return getCanBeCollapsedWithNextDependentAction();
}
/// Return a string containing the offload kind of the action.
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 15b6fdcb8a574..8984c93ce1995 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -23,6 +23,7 @@
#include "clang/Options/Options.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Arg.h"
@@ -187,7 +188,7 @@ class Driver {
/// FIXME: This type of customization should be removed in favor of the
/// universal driver when it is ready.
typedef SmallVector<std::string, 4> prefix_list;
- prefix_list PrefixDirs;
+ llvm::SmallVectorWithFlagsFor<prefix_list, 2> PrefixDirs;
/// sysroot, if present
std::string SysRoot;
@@ -236,13 +237,15 @@ class Driver {
bool IsDXCMode() const { return Mode == DXCMode; }
/// Only print tool bindings, don't build any jobs.
- LLVM_PREFERRED_TYPE(bool)
- unsigned CCCPrintBindings : 1;
+ unsigned getCCCPrintBindings() const { return PrefixDirs.getFlag(0); }
+ void setCCCPrintBindings(unsigned Value) {
+ PrefixDirs.setFlag(0, (Value & 1));
+ }
/// Set CC_PRINT_OPTIONS mode, which is like -v but logs the commands to
/// CCPrintOptionsFilename or to stderr.
- LLVM_PREFERRED_TYPE(bool)
- unsigned CCPrintOptions : 1;
+ unsigned getCCPrintOptions() const { return PrefixDirs.getFlag(1); }
+ void setCCPrintOptions(unsigned Value) { PrefixDirs.setFlag(1, (Value & 1)); }
/// The format of the header information that is emitted. If CC_PRINT_HEADERS
/// is set, the format is textual. Otherwise, the format is determined by the
diff --git a/clang/include/clang/Driver/OffloadBundler.h b/clang/include/clang/Driver/OffloadBundler.h
index 96839240543af..f15a3c9d2d2a8 100644
--- a/clang/include/clang/Driver/OffloadBundler.h
+++ b/clang/include/clang/Driver/OffloadBundler.h
@@ -18,6 +18,7 @@
#define LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Error.h"
#include "llvm/TargetParser/Triple.h"
@@ -30,13 +31,28 @@ class OffloadBundlerConfig {
public:
OffloadBundlerConfig();
- bool AllowNoHost = false;
- bool AllowMissingBundles = false;
- bool CheckInputArchive = false;
- bool PrintExternalCommands = false;
- bool HipOpenmpCompatible = false;
- bool Compress = false;
- bool Verbose = false;
+ bool getAllowNoHost() const { return OutputFileNames.getFlag(0); }
+ void setAllowNoHost(bool Value) { OutputFileNames.setFlag(0, Value); }
+ bool getAllowMissingBundles() const { return OutputFileNames.getFlag(1); }
+ void setAllowMissingBundles(bool Value) { OutputFileNames.setFlag(1, Value); }
+ bool getCheckInputArchive() const { return OutputFileNames.getFlag(2); }
+ void setCheckInputArchive(bool Value) { OutputFileNames.setFlag(2, Value); }
+ bool getPrintExternalCommands() const { return OutputFileNames.getFlag(3); }
+ void setPrintExternalCommands(bool Value) {
+ OutputFileNames.setFlag(3, Value);
+ }
+ bool getHipOpenmpCompatible() const { return InputFileNames.getFlag(0); }
+ void setHipOpenmpCompatible(bool Value) { InputFileNames.setFlag(0, Value); }
+ bool getCompress() const { return InputFileNames.getFlag(1); }
+ bool setCompress(bool Value) {
+ InputFileNames.setFlag(1, Value);
+ return Value;
+ }
+ bool getVerbose() const { return InputFileNames.getFlag(2); }
+ bool setVerbose(bool Value) {
+ InputFileNames.setFlag(2, Value);
+ return Value;
+ }
llvm::compression::Format CompressionFormat;
int CompressionLevel;
uint16_t CompressedBundleVersion;
@@ -48,8 +64,8 @@ class OffloadBundlerConfig {
std::string ObjcopyPath;
llvm::SmallVector<std::string, 4> TargetNames;
- llvm::SmallVector<std::string, 4> InputFileNames;
- llvm::SmallVector<std::string, 4> OutputFileNames;
+ llvm::SmallVectorWithFlags<std::string, 4, 3> InputFileNames;
+ llvm::SmallVectorWithFlags<std::string, 4, 4> OutputFileNames;
};
class OffloadBundler {
diff --git a/clang/include/clang/Driver/RocmInstallationDetector.h b/clang/include/clang/Driver/RocmInstallationDetector.h
index 6481507692b25..824b2a318e277 100644
--- a/clang/include/clang/Driver/RocmInstallationDetector.h
+++ b/clang/include/clang/Driver/RocmInstallationDetector.h
@@ -10,6 +10,7 @@
#define LLVM_CLANG_DRIVER_ROCMINSTALLATIONDETECTOR_H
#include "clang/Driver/Driver.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
namespace driver {
@@ -120,7 +121,8 @@ class RocmInstallationDetector {
// HIP version specified by --hip-version.
StringRef HIPVersionArg;
// Wheter -nogpulib is specified.
- bool NoBuiltinLibs = false;
+ bool getNoBuiltinLibs() const { return ROCmSearchDirs.getFlag(0); }
+ void setNoBuiltinLibs(bool Value) { ROCmSearchDirs.setFlag(0, Value); }
// Paths
SmallString<0> InstallPath;
@@ -151,9 +153,11 @@ class RocmInstallationDetector {
std::map<unsigned, std::string> ABIVersionMap;
// Cache ROCm installation search paths.
- SmallVector<Candidate, 4> ROCmSearchDirs;
- bool PrintROCmSearchDirs;
- bool Verbose;
+ llvm::SmallVectorWithFlags<Candidate, 4, 3> ROCmSearchDirs;
+ bool getPrintROCmSearchDirs() const { return ROCmSearchDirs.getFlag(1); }
+ void setPrintROCmSearchDirs(bool Value) { ROCmSearchDirs.setFlag(1, Value); }
+ bool getVerbose() const { return ROCmSearchDirs.getFlag(2); }
+ void setVerbose(bool Value) { ROCmSearchDirs.setFlag(2, Value); }
bool allGenericLibsValid() const {
return !OCML.empty() && !OCKL.empty() && !OpenCL.empty() &&
@@ -162,7 +166,7 @@ class RocmInstallationDetector {
void scanLibDevicePath(llvm::StringRef Path);
bool parseHIPVersionFile(llvm::StringRef V);
- const SmallVectorImpl<Candidate> &getInstallationPathCandidates();
+ ArrayRef<Candidate> getInstallationPathCandidates();
/// Find the path to a SPACK package under the ROCm candidate installation
/// directory if the candidate is a SPACK ROCm candidate. \returns empty
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 7304ddc43b63f..9e8f716f84f42 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -185,11 +185,9 @@ class ToolChain {
Tool *getOffloadPackager() const;
Tool *getLinkerWrapper() const;
- /// Track if diagnostics have been emitted for sanitizer arguments already to
- /// avoid duplicate diagnostics.
- mutable bool SanitizerArgsChecked = false;
-
/// Set of BoundArch values which have already had diagnostics emitted.
+ /// A nonempty set also records that common sanitizer-argument diagnostics
+ /// have already been emitted.
mutable llvm::SmallSet<StringRef, 4> BoundArchSanitizerArgsChecked;
/// The effective clang triple for the current Job.
diff --git a/clang/include/clang/Edit/Commit.h b/clang/include/clang/Edit/Commit.h
index f6c7988e28ee1..19955107e2a6b 100644
--- a/clang/include/clang/Edit/Commit.h
+++ b/clang/include/clang/Edit/Commit.h
@@ -13,6 +13,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Edit/FileOffset.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
@@ -54,8 +55,9 @@ class Commit {
const PPConditionalDirectiveRecord *PPRec;
EditedSource *Editor = nullptr;
- bool IsCommitable = true;
- SmallVector<Edit, 8> CachedEdits;
+ bool getIsCommitable() const { return !CachedEdits.getFlag(0); }
+ void setIsCommitable(bool Value) { CachedEdits.setFlag(0, !Value); }
+ llvm::SmallVectorWithFlags<Edit, 8> CachedEdits;
llvm::BumpPtrAllocator StrAlloc;
@@ -65,7 +67,7 @@ class Commit {
const PPConditionalDirectiveRecord *PPRec = nullptr)
: SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec) {}
- bool isCommitable() const { return IsCommitable; }
+ bool isCommitable() const { return getIsCommitable(); }
bool insert(SourceLocation loc, StringRef text, bool afterToken = false,
bool beforePreviousInsertions = false);
diff --git a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
index f8759bf2d8f25..2e2df61ccf468 100644
--- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
+++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
@@ -88,20 +89,23 @@ class SymbolGraphSerializer : public APISetVisitor<SymbolGraphSerializer> {
/// Indicates whether to take into account the extended module. This is only
/// useful for \c serializeSingleSymbolSGF.
- bool ForceEmitToMainModule;
+ bool getForceEmitToMainModule() const { return Hierarchy.getFlag(0); }
+ void setForceEmitToMainModule(bool Value) { Hierarchy.setFlag(0, Value); }
// Stores the references required to construct path components for the
// currently visited APIRecord.
- llvm::SmallVector<SymbolReference, 8> Hierarchy;
+ llvm::SmallVectorWithFlags<SymbolReference, 8, 3> Hierarchy;
/// The list of symbols to ignore.
///
/// Note: This should be consulted before emitting a symbol.
const APIIgnoresList &IgnoresList;
- const bool EmitSymbolLabelsForTesting = false;
+ bool getEmitSymbolLabelsForTesting() const { return Hierarchy.getFlag(1); }
- const bool SkipSymbolsInCategoriesToExternalTypes = false;
+ bool getSkipSymbolsInCategoriesToExternalTypes() const {
+ return Hierarchy.getFlag(2);
+ }
/// The object instantiated by the last call to serializeAPIRecord.
Object *CurrentSymbol = nullptr;
@@ -274,11 +278,12 @@ class SymbolGraphSerializer : public APISetVisitor<SymbolGraphSerializer> {
bool EmitSymbolLabelsForTesting = false,
bool ForceEmitToMainModule = false,
bool SkipSymbolsInCategoriesToExternalTypes = false)
- : Base(API), ForceEmitToMainModule(ForceEmitToMainModule),
- IgnoresList(IgnoresList),
- EmitSymbolLabelsForTesting(EmitSymbolLabelsForTesting),
- SkipSymbolsInCategoriesToExternalTypes(
- SkipSymbolsInCategoriesToExternalTypes) {}
+ : Base(API),
+ Hierarchy(decltype(this->Hierarchy)::withFlags(
+ unsigned(ForceEmitToMainModule) |
+ (unsigned(EmitSymbolLabelsForTesting) << 1) |
+ (unsigned(SkipSymbolsInCategoriesToExternalTypes) << 2))),
+ IgnoresList(IgnoresList) {}
};
} // namespace extractapi
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 92d0bd9d03b4d..7f9afd54db68e 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -35,6 +35,7 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -106,8 +107,18 @@ class ASTUnit {
std::unique_ptr<HeaderSearchOptions> HSOpts;
std::shared_ptr<PreprocessorOptions> PPOpts;
IntrusiveRefCntPtr<ASTReader> Reader;
- bool HadModuleLoaderFatalFailure = false;
- bool StorePreamblesInMemory = false;
+ bool getHadModuleLoaderFatalFailure() const {
+ return PreambleDiagnostics.getFlag(0);
+ }
+ void setHadModuleLoaderFatalFailure(bool Value) {
+ PreambleDiagnostics.setFlag(0, Value);
+ }
+ bool getStorePreamblesInMemory() const {
+ return PreambleDiagnostics.getFlag(1);
+ }
+ void setStorePreamblesInMemory(bool Value) {
+ PreambleDiagnostics.setFlag(1, Value);
+ }
/// Utility struct for managing ASTWriter and its associated data streams.
struct ASTWriterData {
@@ -148,13 +159,17 @@ class ASTUnit {
// OnlyLocalDecls - when true, walking this AST should only visit declarations
// that come from the AST itself, not from included precompiled headers.
// FIXME: This is temporary; eventually, CIndex will always do this.
- bool OnlyLocalDecls = false;
+ bool getOnlyLocalDeclsFlag() const { return PreambleDiagnostics.getFlag(2); }
+ void setOnlyLocalDeclsFlag(bool Value) {
+ PreambleDiagnostics.setFlag(2, Value);
+ }
/// Whether to capture any diagnostics produced.
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None;
/// Track whether the main file was loaded from an AST or not.
- bool MainFileIsAST;
+ bool getMainFileIsAST() const { return PreambleDiagnostics.getFlag(3); }
+ void setMainFileIsAST(bool Value) { PreambleDiagnostics.setFlag(3, Value); }
/// What kind of translation unit this AST represents.
TranslationUnitKind TUKind = TU_Complete;
@@ -186,7 +201,7 @@ class ASTUnit {
std::string OriginalSourceFile;
/// The set of diagnostics produced when creating the preamble.
- SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics;
+ llvm::SmallVectorWithFlags<StandaloneDiagnostic, 4, 4> PreambleDiagnostics;
/// The set of diagnostics produced when creating this
/// translation unit.
@@ -423,7 +438,7 @@ class ASTUnit {
ASTUnit &operator=(const ASTUnit &) = delete;
~ASTUnit();
- bool isMainFileAST() const { return MainFileIsAST; }
+ bool isMainFileAST() const { return getMainFileIsAST(); }
bool isUnsafeToFree() const { return UnsafeToFree; }
void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
@@ -509,7 +524,7 @@ class ASTUnit {
ASTMutationListener *getASTMutationListener();
ASTDeserializationListener *getDeserializationListener();
- bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
+ bool getOnlyLocalDecls() const { return getOnlyLocalDeclsFlag(); }
bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; }
void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; }
diff --git a/clang/include/clang/Lex/Lexer.h b/clang/include/clang/Lex/Lexer.h
index b3d8ccdd2d0e3..895170db993c4 100644
--- a/clang/include/clang/Lex/Lexer.h
+++ b/clang/include/clang/Lex/Lexer.h
@@ -234,7 +234,7 @@ class Lexer : public PreprocessorLexer {
/// associated preprocessor object. Return true if the 'next character to
/// read' pointer points at the end of the lexer buffer, false otherwise.
bool LexFromRawLexer(Token &Result) {
- assert(LexingRawMode && "Not already in raw mode!");
+ assert(getLexingRawMode() && "Not already in raw mode!");
Lex(Result);
// Note that lexing to the end of the buffer doesn't implicitly delete the
// lexer when in raw mode.
@@ -252,7 +252,7 @@ class Lexer : public PreprocessorLexer {
/// SetKeepWhitespaceMode - This method lets clients enable or disable
/// whitespace retention mode.
void SetKeepWhitespaceMode(bool Val) {
- assert((!Val || LexingRawMode || LangOpts.TraditionalCPP) &&
+ assert((!Val || getLexingRawMode() || LangOpts.TraditionalCPP) &&
"Can only retain whitespace in raw mode or -traditional-cpp");
ExtendedTokenMode = Val ? 2 : 0;
}
diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h
index 18e77cc28ce4b..3e2bb664a0b3e 100644
--- a/clang/include/clang/Lex/ModuleMap.h
+++ b/clang/include/clang/Lex/ModuleMap.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
@@ -245,8 +246,10 @@ class ModuleMap {
/// A directory for which framework modules can be inferred.
struct InferredDirectory {
/// Whether to infer modules from this directory.
- LLVM_PREFERRED_TYPE(bool)
- unsigned InferModules : 1;
+ unsigned getInferModules() const { return ExcludedModules.getFlag(0); }
+ void setInferModules(unsigned Value) {
+ ExcludedModules.setFlag(0, (Value & 1));
+ }
/// The attributes to use for inferred modules.
Attributes Attrs;
@@ -257,9 +260,9 @@ class ModuleMap {
/// The names of modules that cannot be inferred within this
/// directory.
- SmallVector<std::string, 2> ExcludedModules;
+ llvm::SmallVectorWithFlags<std::string, 2> ExcludedModules;
- InferredDirectory() : InferModules(false) {}
+ InferredDirectory() {}
};
/// A mapping from directories to information about inferring
@@ -319,7 +322,8 @@ class ModuleMap {
///
/// \returns The resolved module, or null if the module-id could not be
/// resolved.
- Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
+ Module *resolveModuleId(llvm::ArrayRef<ModuleId::value_type> Id, Module *Mod,
+ bool Complain) const;
/// Add an unresolved header to a module.
///
@@ -646,7 +650,7 @@ class ModuleMap {
/// Check whether a framework module can be inferred in the given directory.
bool canInferFrameworkModule(const DirectoryEntry *Dir) const {
auto It = InferredDirectories.find(Dir);
- return It != InferredDirectories.end() && It->getSecond().InferModules;
+ return It != InferredDirectories.end() && It->getSecond().getInferModules();
}
/// Retrieve the module map file containing the definition of the given
diff --git a/clang/include/clang/Lex/ModuleMapFile.h b/clang/include/clang/Lex/ModuleMapFile.h
index 59389cd85a928..37658dc037cce 100644
--- a/clang/include/clang/Lex/ModuleMapFile.h
+++ b/clang/include/clang/Lex/ModuleMapFile.h
@@ -10,6 +10,7 @@
#define LLVM_CLANG_LEX_MODULEMAPFILE_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
// TODO: Consider moving ModuleId to another header, parsing a modulemap file is
// intended to not depend on anything about the clang::Module class.
#include "clang/Basic/Module.h"
@@ -68,15 +69,15 @@ struct UmbrellaDirDecl {
};
struct ModuleDecl {
- ModuleId Id;
+ llvm::SmallVectorWithFlagsFor<ModuleId, 2> Id;
SourceLocation Location; /// Points to the first keyword in the decl.
ModuleAttributes Attrs;
std::vector<Decl> Decls;
- LLVM_PREFERRED_TYPE(bool)
- unsigned Explicit : 1;
- LLVM_PREFERRED_TYPE(bool)
- unsigned Framework : 1;
+ unsigned getExplicit() const { return Id.getFlag(0); }
+ void setExplicit(unsigned Value) { Id.setFlag(0, (Value & 1)); }
+ unsigned getFramework() const { return Id.getFlag(1); }
+ void setFramework(unsigned Value) { Id.setFlag(1, (Value & 1)); }
};
struct ExcludeDecl {
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h
index 31b68a0fd0670..97a04b7142c1d 100644
--- a/clang/include/clang/Lex/Preprocessor.h
+++ b/clang/include/clang/Lex/Preprocessor.h
@@ -43,6 +43,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/iterator_range.h"
@@ -297,13 +298,28 @@ class Preprocessor {
bool PragmasEnabled : 1;
/// True if the current build action is a preprocessing action.
- bool PreprocessedOutput : 1;
+ bool getPreprocessedOutputFlag() const {
+ return PendingModuleMacroNames.getFlag(0);
+ }
+ void setPreprocessedOutputFlag(bool Value) {
+ PendingModuleMacroNames.setFlag(0, Value);
+ }
/// True if we are currently preprocessing a #if or #elif directive
- bool ParsingIfOrElifDirective;
+ bool getParsingIfOrElifDirective() const {
+ return PendingModuleMacroNames.getFlag(1);
+ }
+ void setParsingIfOrElifDirective(bool Value) {
+ PendingModuleMacroNames.setFlag(1, Value);
+ }
/// True if we are pre-expanding macro arguments.
- bool InMacroArgPreExpansion;
+ bool getInMacroArgPreExpansion() const {
+ return PendingModuleMacroNames.getFlag(2);
+ }
+ void setInMacroArgPreExpansion(bool Value) {
+ PendingModuleMacroNames.setFlag(2, Value);
+ }
/// Mapping/lookup information for all identifiers in
/// the program, including program keywords.
@@ -339,7 +355,12 @@ class Preprocessor {
EmptylineHandler *Emptyline = nullptr;
/// True to avoid tearing down the lexer etc on EOF
- bool IncrementalProcessing = false;
+ bool getIncrementalProcessing() const {
+ return PendingModuleMacroNames.getFlag(3);
+ }
+ void setIncrementalProcessing(bool Value) {
+ PendingModuleMacroNames.setFlag(3, Value);
+ }
public:
/// The kind of translation unit we are processing.
@@ -384,10 +405,20 @@ class Preprocessor {
unsigned CheckPointCounter = 0;
/// Whether to record lexer check points for diagnostic snippet highlighting.
- bool RecordCheckPoints = false;
+ bool getRecordCheckPoints() const {
+ return BuildingSubmoduleStack.getFlag(0);
+ }
+ void setRecordCheckPoints(bool Value) {
+ BuildingSubmoduleStack.setFlag(0, Value);
+ }
/// Whether we're importing a standard C++20 named Modules.
- bool ImportingCXXNamedModules = false;
+ bool getImportingCXXNamedModules() const {
+ return BuildingSubmoduleStack.getFlag(1);
+ }
+ void setImportingCXXNamedModules(bool Value) {
+ BuildingSubmoduleStack.setFlag(1, Value);
+ }
/// Whether the last token we lexed was an 'export' keyword.
Token LastExportKeyword;
@@ -690,7 +721,12 @@ class Preprocessor {
SourceLocation PreambleRecordedPragmaAssumeNonNullLoc;
/// True if we hit the code-completion point.
- bool CodeCompletionReached = false;
+ bool getCodeCompletionReachedFlag() const {
+ return BuildingSubmoduleStack.getFlag(2);
+ }
+ void setCodeCompletionReachedFlag(bool Value) {
+ BuildingSubmoduleStack.setFlag(2, Value);
+ }
/// The code completion token containing the information
/// on the stem that is to be code completed.
@@ -719,11 +755,26 @@ class Preprocessor {
FileID DeferredGMFInputsFileID;
/// Whether the predefines buffer contains a synthesized GMF introducer.
- bool HasSynthesizedGMF = false;
+ bool getHasSynthesizedGMF() const {
+ return BuildingSubmoduleStack.getFlag(3);
+ }
+ void setHasSynthesizedGMF(bool Value) {
+ BuildingSubmoduleStack.setFlag(3, Value);
+ }
/// Whether setPredefines() replaced a previously initialized buffer.
- bool PredefinesWereReplaced = false;
- bool PredefinesInitialized = false;
+ bool getPredefinesWereReplaced() const {
+ return DelayedMacroExpandsCallbacks.getFlag(0);
+ }
+ void setPredefinesWereReplaced(bool Value) {
+ DelayedMacroExpandsCallbacks.setFlag(0, Value);
+ }
+ bool getPredefinesInitialized() const {
+ return DelayedMacroExpandsCallbacks.getFlag(1);
+ }
+ void setPredefinesInitialized(bool Value) {
+ DelayedMacroExpandsCallbacks.setFlag(1, Value);
+ }
bool hasDeferredGMFInputs() const { return !DeferredGMFInputs.empty(); }
@@ -732,7 +783,12 @@ class Preprocessor {
/// Whether we hit an error due to reaching max allowed include depth. Allows
/// to avoid hitting the same error over and over again.
- bool HasReachedMaxIncludeDepth = false;
+ bool getHasReachedMaxIncludeDepth() const {
+ return DelayedMacroExpandsCallbacks.getFlag(2);
+ }
+ void setHasReachedMaxIncludeDepth(bool Value) {
+ DelayedMacroExpandsCallbacks.setFlag(2, Value);
+ }
/// The number of currently-active calls to Lex.
///
@@ -746,7 +802,12 @@ class Preprocessor {
unsigned TokenCount = 0;
/// Preprocess every token regardless of LexLevel.
- bool PreprocessToken = false;
+ bool getPreprocessTokenFlag() const {
+ return DelayedMacroExpandsCallbacks.getFlag(3);
+ }
+ void setPreprocessTokenFlag(bool Value) {
+ DelayedMacroExpandsCallbacks.setFlag(3, Value);
+ }
/// The maximum number of (LexLevel 0) tokens before issuing a -Wmax-tokens
/// warning, or zero for unlimited.
@@ -829,7 +890,7 @@ class Preprocessor {
/// Stack of Lexer unwinds completely (LexLevel returns to 0).
/// This avoids use-after-free when HandleEndOfFile is called from
/// within a Lexer method that still needs to access its members.
- SmallVector<std::unique_ptr<Lexer>, 2> PendingDestroyLexers;
+ llvm::SmallVectorWithFlags<std::unique_ptr<Lexer>, 2, 4> PendingDestroyLexers;
/// The current top of the stack that we're lexing from
/// if not expanding a macro.
@@ -895,7 +956,8 @@ class Preprocessor {
MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range)
: Tok(Tok), MD(MD), Range(Range) {}
};
- SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
+ llvm::SmallVectorWithFlags<MacroExpandsInfo, 2, 4>
+ DelayedMacroExpandsCallbacks;
/// Information about a name that has been used to define a module macro.
struct FullModuleMacroInfo {
@@ -1061,7 +1123,8 @@ class Preprocessor {
OuterSubmoduleState(OuterSubmoduleState),
OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
};
- SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
+ llvm::SmallVectorWithFlags<BuildingSubmoduleInfo, 8, 4>
+ BuildingSubmoduleStack;
/// Information about a submodule's preprocessor state.
struct SubmoduleState {
@@ -1094,7 +1157,7 @@ class Preprocessor {
llvm::UniquingSet<ModuleMacro> ModuleMacros;
/// The names of potential module macros that we've not yet processed.
- llvm::SmallVector<IdentifierInfo *, 32> PendingModuleMacroNames;
+ llvm::SmallVectorWithFlags<IdentifierInfo *, 32, 4> PendingModuleMacroNames;
/// The list of module macros, for each identifier, that are not overridden by
/// any other module macro.
@@ -1170,13 +1233,31 @@ class Preprocessor {
FileID PCHThroughHeaderFileID;
/// Whether tokens are being skipped until a #pragma hdrstop is seen.
- bool SkippingUntilPragmaHdrStop = false;
+ bool getSkippingUntilPragmaHdrStop() const {
+ return PendingDestroyLexers.getFlag(0);
+ }
+ bool setSkippingUntilPragmaHdrStop(bool Value) {
+ PendingDestroyLexers.setFlag(0, Value);
+ return Value;
+ }
/// Whether tokens are being skipped until the through header is seen.
- bool SkippingUntilPCHThroughHeader = false;
+ bool getSkippingUntilPCHThroughHeader() const {
+ return PendingDestroyLexers.getFlag(1);
+ }
+ bool setSkippingUntilPCHThroughHeader(bool Value) {
+ PendingDestroyLexers.setFlag(1, Value);
+ return Value;
+ }
/// Whether the main file is preprocessed module file.
- bool MainFileIsPreprocessedModuleFile = false;
+ bool getMainFileIsPreprocessedModuleFile() const {
+ return PendingDestroyLexers.getFlag(2);
+ }
+ bool setMainFileIsPreprocessedModuleFile(bool Value) {
+ PendingDestroyLexers.setFlag(2, Value);
+ return Value;
+ }
/// \{
/// Cache of macro expanders to reduce malloc traffic.
@@ -1230,7 +1311,12 @@ class Preprocessor {
/// This is used to guard against calling this function recursively.
///
/// See comments at the use-site for more context about why it is needed.
- bool SkippingExcludedConditionalBlock = false;
+ bool getSkippingExcludedConditionalBlock() const {
+ return PendingDestroyLexers.getFlag(3);
+ }
+ void setSkippingExcludedConditionalBlock(bool Value) {
+ PendingDestroyLexers.setFlag(3, Value);
+ }
/// Keeps track of skipped range mappings that were recorded while skipping
/// excluded conditional directives. It maps the source buffer pointer at
@@ -1313,7 +1399,7 @@ class Preprocessor {
/// True if we are currently preprocessing a #if or #elif directive
bool isParsingIfOrElifDirective() const {
- return ParsingIfOrElifDirective;
+ return getParsingIfOrElifDirective();
}
/// Control whether the preprocessor retains comments in output.
@@ -1338,12 +1424,12 @@ class Preprocessor {
/// Sets whether the preprocessor is responsible for producing output or if
/// it is producing tokens to be consumed by Parse and Sema.
void setPreprocessedOutput(bool IsPreprocessedOutput) {
- PreprocessedOutput = IsPreprocessedOutput;
+ setPreprocessedOutputFlag(IsPreprocessedOutput);
}
/// Returns true if the preprocessor is responsible for generating output,
/// false if it is producing tokens to be consumed by Parse and Sema.
- bool isPreprocessedOutput() const { return PreprocessedOutput; }
+ bool isPreprocessedOutput() const { return getPreprocessedOutputFlag(); }
/// Return true if we are lexing directly from the specified lexer.
bool isCurrentLexer(const PreprocessorLexer *L) const {
@@ -1408,7 +1494,9 @@ class Preprocessor {
GetDependencyDirectives = &Get;
}
- void setPreprocessToken(bool Preprocess) { PreprocessToken = Preprocess; }
+ void setPreprocessToken(bool Preprocess) {
+ setPreprocessTokenFlag(Preprocess);
+ }
bool isMacroDefined(StringRef Id) {
return isMacroDefined(&Identifiers.get(Id));
@@ -1589,8 +1677,9 @@ class Preprocessor {
///
/// These predefines are automatically injected when parsing the main file.
void setPredefines(std::string P) {
- PredefinesWereReplaced |= PredefinesInitialized;
- PredefinesInitialized = true;
+ setPredefinesWereReplaced(int(getPredefinesWereReplaced()) |
+ (getPredefinesInitialized()));
+ setPredefinesInitialized(true);
Predefines = std::move(P);
}
@@ -1835,14 +1924,14 @@ class Preprocessor {
/// Whether the main file is preprocessed module file.
bool isPreprocessedModuleFile() const {
- return MainFileIsPreprocessedModuleFile;
+ return getMainFileIsPreprocessedModuleFile();
}
/// Mark the main file as a preprocessed module file, then the 'module' and
/// 'import' directive recognition will be suppressed. Only
/// '__preprocessed_moduke' and '__preprocessed_import' are allowed.
void markMainFileAsPreprocessedModuleFile() {
- MainFileIsPreprocessedModuleFile = true;
+ setMainFileIsPreprocessedModuleFile(true);
}
bool LexModuleNameContinue(Token &Tok, SourceLocation UseLoc,
@@ -2069,11 +2158,13 @@ class Preprocessor {
void recomputeCurLexerKind();
/// Returns true if incremental processing is enabled
- bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
+ bool isIncrementalProcessingEnabled() const {
+ return getIncrementalProcessing();
+ }
/// Enables the incremental processing
void enableIncrementalProcessing(bool value = true) {
- IncrementalProcessing = value;
+ setIncrementalProcessing(value);
}
/// Specify the point at which code-completion will be performed.
@@ -2112,12 +2203,14 @@ class Preprocessor {
/// Returns true if code-completion is enabled and we have hit the
/// code-completion point.
- bool isCodeCompletionReached() const { return CodeCompletionReached; }
+ bool isCodeCompletionReached() const {
+ return getCodeCompletionReachedFlag();
+ }
/// Note that we hit the code-completion point.
void setCodeCompletionReached() {
assert(isCodeCompletionEnabled() && "Code-completion not enabled!");
- CodeCompletionReached = true;
+ setCodeCompletionReachedFlag(true);
// Silence any diagnostics that occur after we hit the code-completion.
getDiagnostics().setSuppressAllDiagnostics(true);
}
@@ -2571,7 +2664,7 @@ class Preprocessor {
bool isImportingCXXNamedModules() const {
assert(getLangOpts().CPlusPlusModules &&
"Import C++ named modules are only valid for C++20 modules");
- return ImportingCXXNamedModules;
+ return getImportingCXXNamedModules();
}
/// Allocate a new MacroInfo object with the provided SourceLocation.
diff --git a/clang/include/clang/Lex/PreprocessorLexer.h b/clang/include/clang/Lex/PreprocessorLexer.h
index d71fe708ab20a..1435161f9edae 100644
--- a/clang/include/clang/Lex/PreprocessorLexer.h
+++ b/clang/include/clang/Lex/PreprocessorLexer.h
@@ -20,6 +20,7 @@
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <cassert>
namespace clang {
@@ -47,10 +48,17 @@ class PreprocessorLexer {
//===--------------------------------------------------------------------===//
/// True when parsing \#XXX; turns '\\n' into a tok::eod token.
- bool ParsingPreprocessorDirective = false;
+ bool getParsingPreprocessorDirectiveFlag() const {
+ return ConditionalStack.getFlag(0);
+ }
+ bool setParsingPreprocessorDirectiveFlag(bool Value) {
+ ConditionalStack.setFlag(0, Value);
+ return Value;
+ }
/// True after \#include; turns \<xx> or "xxx" into a tok::header_name token.
- bool ParsingFilename = false;
+ bool getParsingFilename() const { return ConditionalStack.getFlag(1); }
+ void setParsingFilename(bool Value) { ConditionalStack.setFlag(1, Value); }
/// True if in raw mode.
///
@@ -65,7 +73,11 @@ class PreprocessorLexer {
/// 5. No callbacks are made into the preprocessor.
///
/// Note that in raw mode that the PP pointer may be null.
- bool LexingRawMode = false;
+ bool getLexingRawMode() const { return ConditionalStack.getFlag(2); }
+ bool setLexingRawMode(bool Value) {
+ ConditionalStack.setFlag(2, Value);
+ return Value;
+ }
/// A state machine that detects the \#ifndef-wrapping a file
/// idiom for the multiple-include optimization.
@@ -73,7 +85,7 @@ class PreprocessorLexer {
/// Information about the set of \#if/\#ifdef/\#ifndef blocks
/// we are currently in.
- SmallVector<PPConditionalInfo, 4> ConditionalStack;
+ llvm::SmallVectorWithFlags<PPConditionalInfo, 4, 3> ConditionalStack;
PreprocessorLexer() : FID() {}
PreprocessorLexer(Preprocessor *pp, FileID fid);
@@ -135,11 +147,11 @@ class PreprocessorLexer {
/// Inform the lexer whether or not we are currently lexing a
/// preprocessor directive.
void setParsingPreprocessorDirective(bool f) {
- ParsingPreprocessorDirective = f;
+ setParsingPreprocessorDirectiveFlag(f);
}
/// Return true if this lexer is in raw mode or not.
- bool isLexingRawMode() const { return LexingRawMode; }
+ bool isLexingRawMode() const { return getLexingRawMode(); }
/// Return the preprocessor object for this lexer.
Preprocessor *getPP() const { return PP; }
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 9a1abd4f3872d..cf5d119118201 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -23,6 +23,7 @@
#include "clang/Sema/SemaOpenMP.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Frontend/OpenMP/OMPContext.h"
#include "llvm/Support/SaveAndRestore.h"
#include <optional>
@@ -684,7 +685,12 @@ class Parser : public CodeCompletionHandler {
/// Gets set to true after calling ProduceSignatureHelp, it is for a
/// workaround to make sure ProduceSignatureHelp is only called at the deepest
/// function call.
- bool CalledSignatureHelp = false;
+ bool getCalledSignatureHelp() const {
+ return TentativelyDeclaredIdentifiers.getFlag(0);
+ }
+ void setCalledSignatureHelp(bool Value) {
+ TentativelyDeclaredIdentifiers.setFlag(0, Value);
+ }
bool isTokenSEHExcept();
@@ -692,7 +698,12 @@ class Parser : public CodeCompletionHandler {
///
/// This option can be used, for example, to speed up searches for
/// declarations/definitions when indexing.
- bool SkipFunctionBodies;
+ bool getSkipFunctionBodies() const {
+ return TentativelyDeclaredIdentifiers.getFlag(1);
+ }
+ void setSkipFunctionBodies(bool Value) {
+ TentativelyDeclaredIdentifiers.setFlag(1, Value);
+ }
//===--------------------------------------------------------------------===//
// Low-Level token peeking and consumption methods.
@@ -1353,7 +1364,7 @@ class Parser : public CodeCompletionHandler {
/// the method declarations and possibly attached inline definitions
/// will be stored here with the tokens that will be parsed to create those
/// entities.
- typedef SmallVector<LateParsedDeclaration *, 2>
+ typedef llvm::SmallVectorWithFlags<LateParsedDeclaration *, 2, 2>
LateParsedDeclarationsContainer;
/// Utility to re-enter a possibly-templated scope while parsing its
@@ -2919,15 +2930,17 @@ class Parser : public CodeCompletionHandler {
/// parsed after the corresponding top-level class is complete.
struct ParsingClass {
ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface)
- : TopLevelClass(TopLevelClass), IsInterface(IsInterface),
- TagOrTemplate(TagOrTemplate) {}
+ : TagOrTemplate(TagOrTemplate) {
+ LateParsedDeclarations.setFlag(0, TopLevelClass);
+ LateParsedDeclarations.setFlag(1, IsInterface);
+ }
/// Whether this is a "top-level" class, meaning that it is
/// not nested within another class.
- bool TopLevelClass : 1;
+ bool isTopLevelClass() const { return LateParsedDeclarations.getFlag(0); }
/// Whether this class is an __interface.
- bool IsInterface : 1;
+ bool isInterface() const { return LateParsedDeclarations.getFlag(1); }
/// The class or class template whose definition we are parsing.
Decl *TagOrTemplate;
@@ -4522,12 +4535,22 @@ class Parser : public CodeCompletionHandler {
/// code like "foo : bar" as if it were a typo for "foo :: bar". This is not
/// safe in case statements and a few other things. This is managed by the
/// ColonProtectionRAIIObject RAII object.
- bool ColonIsSacred;
+ bool getColonIsSacred() const {
+ return TentativelyDeclaredIdentifiers.getFlag(2);
+ }
+ void setColonIsSacred(bool Value) {
+ TentativelyDeclaredIdentifiers.setFlag(2, Value);
+ }
// ParsingGenericAssociationType - Currently parsing the typename in
// _Generic association. This is to consume the colon if what comes after it
// is a type.
- bool ParsingGenericAssociationType;
+ bool getParsingGenericAssociationType() const {
+ return TentativelyDeclaredIdentifiers.getFlag(3);
+ }
+ void setParsingGenericAssociationType(bool Value) {
+ TentativelyDeclaredIdentifiers.setFlag(3, Value);
+ }
/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a
/// parenthesized ambiguous type-id. This uses tentative parsing to
@@ -5740,20 +5763,23 @@ class Parser : public CodeCompletionHandler {
struct ObjCImplParsingDataRAII {
Parser &P;
Decl *Dcl;
- bool HasCFunction;
+ bool getHasCFunction() const { return LateParsedObjCMethods.getFlag(0); }
+ void setHasCFunction(bool Value) {
+ LateParsedObjCMethods.setFlag(0, Value);
+ }
typedef SmallVector<LexedMethod *, 8> LateParsedObjCMethodContainer;
- LateParsedObjCMethodContainer LateParsedObjCMethods;
+ llvm::SmallVectorWithFlagsFor<LateParsedObjCMethodContainer, 2>
+ LateParsedObjCMethods;
ObjCImplParsingDataRAII(Parser &parser, Decl *D)
- : P(parser), Dcl(D), HasCFunction(false),
- PrevParsedObjCImpl(parser.CurParsedObjCImpl) {
+ : P(parser), Dcl(D), PrevParsedObjCImpl(parser.CurParsedObjCImpl) {
P.CurParsedObjCImpl = this;
- Finished = false;
+ setFinished(false);
}
~ObjCImplParsingDataRAII();
void finish(SourceRange AtEnd);
- bool isFinished() const { return Finished; }
+ bool isFinished() const { return getFinished(); }
private:
/// The \@implementation that was still open when this one started; made
@@ -5762,7 +5788,8 @@ class Parser : public CodeCompletionHandler {
/// still open (e.g. through an intervening namespace). For valid code
/// this is always null.
ObjCImplParsingDataRAII *PrevParsedObjCImpl;
- bool Finished;
+ bool getFinished() const { return LateParsedObjCMethods.getFlag(1); }
+ void setFinished(bool Value) { LateParsedObjCMethods.setFlag(1, Value); }
};
ObjCImplParsingDataRAII *CurParsedObjCImpl;
@@ -6226,10 +6253,11 @@ class Parser : public CodeCompletionHandler {
};
struct OpenACCWaitParseInfo {
- bool Failed = false;
+ bool getFailed() const { return QueueIdExprs.getFlag(0); }
+ void setFailed(bool Value) { QueueIdExprs.setFlag(0, Value); }
Expr *DevNumExpr = nullptr;
SourceLocation QueuesLoc;
- SmallVector<Expr *> QueueIdExprs;
+ llvm::SmallVectorWithFlags<Expr *> QueueIdExprs;
SmallVector<Expr *> getAllExprs() {
SmallVector<Expr *> Out;
@@ -8037,7 +8065,8 @@ class Parser : public CodeCompletionHandler {
};
/// Identifiers which have been declared within a tentative parse.
- SmallVector<const IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
+ llvm::SmallVectorWithFlags<const IdentifierInfo *, 8, 4>
+ TentativelyDeclaredIdentifiers;
/// Tracker for '<' tokens that might have been intended to be treated as an
/// angle bracket instead of a less-than comparison.
diff --git a/clang/include/clang/Parse/RAIIObjectsForParser.h b/clang/include/clang/Parse/RAIIObjectsForParser.h
index 7b2c9c6c049a4..bd1b645da346a 100644
--- a/clang/include/clang/Parse/RAIIObjectsForParser.h
+++ b/clang/include/clang/Parse/RAIIObjectsForParser.h
@@ -275,15 +275,13 @@ namespace clang {
bool OldVal;
public:
ColonProtectionRAIIObject(Parser &p, bool Value = true)
- : P(p), OldVal(P.ColonIsSacred) {
- P.ColonIsSacred = Value;
+ : P(p), OldVal(P.getColonIsSacred()) {
+ P.setColonIsSacred(Value);
}
/// restore - This can be used to restore the state early, before the dtor
/// is run.
- void restore() {
- P.ColonIsSacred = OldVal;
- }
+ void restore() { P.setColonIsSacred(OldVal); }
~ColonProtectionRAIIObject() {
restore();
@@ -296,8 +294,8 @@ namespace clang {
public:
GenericAssociationTypeRAIIObject(Parser &P, bool Value = true)
- : P(P), OldVal(P.ParsingGenericAssociationType) {
- P.ParsingGenericAssociationType = Value;
+ : P(P), OldVal(P.getParsingGenericAssociationType()) {
+ P.setParsingGenericAssociationType(Value);
}
GenericAssociationTypeRAIIObject(const GenericAssociationTypeRAIIObject &) =
@@ -305,7 +303,7 @@ namespace clang {
GenericAssociationTypeRAIIObject &
operator=(const GenericAssociationTypeRAIIObject &) = delete;
- void restore() { P.ParsingGenericAssociationType = OldVal; }
+ void restore() { P.setParsingGenericAssociationType(OldVal); }
~GenericAssociationTypeRAIIObject() { restore(); }
};
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 66a6098a75ae9..14ebb7c9e7c2a 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -34,6 +34,7 @@
#include "clang/Sema/ParsedAttr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <optional>
@@ -1259,28 +1260,24 @@ class UnqualifiedId {
typedef SmallVector<Token, 4> CachedTokens;
// A list of late-parsed attributes. Used by ParseGNUAttributes.
-class LateParsedAttrList : public SmallVector<LateParsedAttribute *, 2> {
+class LateParsedAttrList
+ : public llvm::SmallVectorWithFlags<LateParsedAttribute *, 2, 3> {
public:
LateParsedAttrList(bool PSoon = false,
bool LateAttrParseExperimentalExtOnly = false,
- bool LateAttrParseTypeAttrOnly = false)
- : ParseSoon(PSoon),
- LateAttrParseExperimentalExtOnly(LateAttrParseExperimentalExtOnly),
- LateAttrParseTypeAttrOnly(LateAttrParseTypeAttrOnly) {}
+ bool LateAttrParseTypeAttrOnly = false) {
+ // Flag bits 0-2 select immediate parsing and the two attribute filters.
+ setFlags(unsigned(PSoon) |
+ (unsigned(LateAttrParseExperimentalExtOnly) << 1) |
+ (unsigned(LateAttrParseTypeAttrOnly) << 2));
+ }
- bool parseSoon() const { return ParseSoon; }
+ bool parseSoon() const { return getFlag(0); }
/// returns true iff the attribute to be parsed should only be late parsed
/// if it is annotated with `LateAttrParseExperimentalExt`
- bool lateAttrParseExperimentalExtOnly() const {
- return LateAttrParseExperimentalExtOnly;
- }
+ bool lateAttrParseExperimentalExtOnly() const { return getFlag(1); }
- bool lateAttrParseTypeAttrOnly() const { return LateAttrParseTypeAttrOnly; }
-
-private:
- bool ParseSoon; // Are we planning to parse these shortly after creation?
- bool LateAttrParseExperimentalExtOnly;
- bool LateAttrParseTypeAttrOnly;
+ bool lateAttrParseTypeAttrOnly() const { return getFlag(2); }
};
/// One instance of this struct is used for each type in a
diff --git a/clang/include/clang/Sema/ScopeInfo.h b/clang/include/clang/Sema/ScopeInfo.h
index 8dc40a5bc58bd..623e232c18759 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -30,6 +30,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/TinyPtrVector.h"
@@ -723,17 +724,28 @@ class CapturingScopeInfo : public FunctionScopeInfo {
/// - Whether the target type of return statements in this context
/// is deduced (e.g. a lambda or block with omitted return type).
- bool HasImplicitReturnType = false;
+ bool getHasImplicitReturnType() const { return LocalPacks.getFlag(0); }
+ void setHasImplicitReturnType(bool Value) { LocalPacks.setFlag(0, Value); }
/// Whether this contains an unexpanded parameter pack.
- bool ContainsUnexpandedParameterPack = false;
+ bool getContainsUnexpandedParameterPack() const {
+ return LocalPacks.getFlag(1);
+ }
+ void setContainsUnexpandedParameterPack(bool Value) {
+ LocalPacks.setFlag(1, Value);
+ }
+
+ void addUnexpandedParameterPack(bool ContainsPack) {
+ setContainsUnexpandedParameterPack(getContainsUnexpandedParameterPack() |
+ (ContainsPack));
+ }
/// ReturnType - The target type of return statements in this context,
/// or null if unknown.
QualType ReturnType;
/// Packs introduced by this, if any.
- SmallVector<NamedDecl *, 4> LocalPacks;
+ llvm::SmallVectorWithFlags<NamedDecl *, 4, 2> LocalPacks;
void addCapture(ValueDecl *Var, bool isBlock, bool isByref, bool isNested,
SourceLocation Loc, SourceLocation EllipsisLoc,
@@ -877,9 +889,13 @@ class LambdaScopeInfo final :
/// Indicate that we parsed the parameter list
/// at which point the mutability of the lambda
/// is known.
- bool AfterParameterList = true;
+ bool getAfterParameterList() const { return !ShadowingDecls.getFlag(0); }
+ void setAfterParameterList(bool Value) { ShadowingDecls.setFlag(0, !Value); }
- bool BeforeCompoundStatement = true;
+ bool getBeforeCompoundStatement() const { return !ShadowingDecls.getFlag(1); }
+ void setBeforeCompoundStatement(bool Value) {
+ ShadowingDecls.setFlag(1, !Value);
+ }
ParmVarDecl *ExplicitObjectParameter = nullptr;
@@ -896,10 +912,15 @@ class LambdaScopeInfo final :
/// Whether this is a mutable lambda. Until the mutable keyword is parsed,
/// we assume the lambda is mutable.
- bool Mutable = true;
+ bool getMutable() const { return !ShadowingDecls.getFlag(2); }
+ void setMutable(bool Value) { ShadowingDecls.setFlag(2, !Value); }
/// Whether the (empty) parameter list is explicit.
- bool ExplicitParams = false;
+ bool getExplicitParams() const { return ShadowingDecls.getFlag(3); }
+ bool setExplicitParams(bool Value) {
+ ShadowingDecls.setFlag(3, Value);
+ return Value;
+ }
/// Whether any of the capture expressions requires cleanups.
CleanupInfo Cleanup;
@@ -948,7 +969,7 @@ class LambdaScopeInfo final :
const NamedDecl *VD;
const NamedDecl *ShadowedDecl;
};
- llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls;
+ llvm::SmallVectorWithFlags<ShadowedOuterDecl, 4, 4> ShadowingDecls;
SourceLocation PotentialThisCaptureLocation;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 865defa98a1b3..cd6a1d25f1d04 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -86,6 +86,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/TinyPtrVector.h"
@@ -1141,7 +1142,12 @@ class Sema final : public SemaBase {
/// Flushed whenever a diagnostic pragma changes severities.
/// Level one is keyed on the diagnostic state alone.
const void *DocDiagsStateKey = nullptr;
- bool DocDiagsEnabledIgnoringSystem = false;
+ bool getDocDiagsEnabledIgnoringSystem() const {
+ return SavedPendingInstantiations.getFlag(0);
+ }
+ void setDocDiagsEnabledIgnoringSystem(bool Value) {
+ SavedPendingInstantiations.setFlag(0, Value);
+ }
/// Level two, for when the location does matter. Bit i of each mask is a
/// DiagStateSystemClass value; bit 0 is unused.
@@ -1392,11 +1398,22 @@ class Sema final : public SemaBase {
/// Is the last error level diagnostic immediate. This is used to determined
/// whether the next info diagnostic should be immediate.
- bool IsLastErrorImmediate = true;
+ bool getIsLastErrorImmediate() const {
+ return !SavedPendingInstantiations.getFlag(1);
+ }
+ bool setIsLastErrorImmediate(bool Value) {
+ SavedPendingInstantiations.setFlag(1, !Value);
+ return Value;
+ }
/// Track if we're currently analyzing overflow behavior types in assignment
/// context.
- bool InOverflowBehaviorAssignmentContext = false;
+ bool getInOverflowBehaviorAssignmentContext() const {
+ return SavedPendingInstantiations.getFlag(2);
+ }
+ void setInOverflowBehaviorAssignmentContext(bool Value) {
+ SavedPendingInstantiations.setFlag(2, Value);
+ }
class DelayedDiagnostics;
@@ -1618,7 +1635,12 @@ class Sema final : public SemaBase {
private:
std::optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo;
- bool WarnedDarwinSDKInfoMissing = false;
+ bool getWarnedDarwinSDKInfoMissing() const {
+ return SavedPendingInstantiations.getFlag(3);
+ }
+ void setWarnedDarwinSDKInfoMissing(bool Value) {
+ SavedPendingInstantiations.setFlag(3, Value);
+ }
StackExhaustionHandler StackHandler;
@@ -1859,7 +1881,10 @@ class Sema final : public SemaBase {
LangOptions::PragmaMSPointersToMembersKind
MSPointerToMemberRepresentationMethod;
- bool MSStructPragmaOn; // True when \#pragma ms_struct on
+ bool getMSStructPragmaOn() const { return SavedVTableUses.getFlag(0); }
+ void setMSStructPragmaOn(bool Value) {
+ SavedVTableUses.setFlag(0, Value);
+ } // True when \#pragma ms_struct on
/// Source location for newly created implicit MSInheritanceAttrs
SourceLocation ImplicitMSInheritanceAttrLoc;
@@ -2149,10 +2174,17 @@ class Sema final : public SemaBase {
/// This an attribute introduced by \#pragma clang attribute.
struct PragmaAttributeEntry {
+ PragmaAttributeEntry(SourceLocation Loc, ParsedAttr *Attribute,
+ SmallVector<attr::SubjectMatchRule, 4> MatchRules,
+ bool IsUsed)
+ : Loc(Loc), Attribute(Attribute),
+ MatchRules(unsigned(IsUsed), std::move(MatchRules)) {}
+
SourceLocation Loc;
ParsedAttr *Attribute;
- SmallVector<attr::SubjectMatchRule, 4> MatchRules;
- bool IsUsed;
+ llvm::SmallVectorWithFlags<attr::SubjectMatchRule, 4> MatchRules;
+ bool getIsUsed() const { return MatchRules.getFlag(0); }
+ void setIsUsed(bool Value) { MatchRules.setFlag(0, Value); }
};
/// A push'd group of PragmaAttributeEntries.
@@ -2186,7 +2218,10 @@ class Sema final : public SemaBase {
/// turned off or on. This boolean is true by default because command line
/// options are honored when `#pragma optimize("", on)`.
/// (i.e. `ModifyFnAttributeMSPragmaOptimze()` does nothing)
- bool MSPragmaOptimizeIsOn = true;
+ bool getMSPragmaOptimizeIsOn() const { return !SavedVTableUses.getFlag(1); }
+ void setMSPragmaOptimizeIsOn(bool Value) {
+ SavedVTableUses.setFlag(1, !Value);
+ }
/// Set of no-builtin functions listed by \#pragma function.
llvm::SmallSetVector<StringRef, 4> MSFunctionNoBuiltins;
@@ -6889,11 +6924,12 @@ class Sema final : public SemaBase {
/// If we are processing a decltype type, a set of call expressions
/// for which we have deferred checking the completeness of the return type.
- SmallVector<CallExpr *, 8> DelayedDecltypeCalls;
+ llvm::SmallVectorWithFlags<CallExpr *, 8, 4> DelayedDecltypeCalls;
/// If we are processing a decltype type, a set of temporary binding
/// expressions for which we have deferred checking the destructor.
- SmallVector<CXXBindTemporaryExpr *, 8> DelayedDecltypeBinds;
+ llvm::SmallVectorWithFlags<CXXBindTemporaryExpr *, 8, 4>
+ DelayedDecltypeBinds;
llvm::SmallPtrSet<const Expr *, 8> PossibleDerefs;
@@ -6932,27 +6968,64 @@ class Sema final : public SemaBase {
// A context can be nested in both a discarded statement context and
// an immediate function context, so they need to be tracked independently.
- bool InDiscardedStatement;
- bool InImmediateFunctionContext;
- bool InImmediateEscalatingFunctionContext;
+ bool getInDiscardedStatement() const {
+ return DelayedDecltypeBinds.getFlag(0);
+ }
+ void setInDiscardedStatement(bool Value) {
+ DelayedDecltypeBinds.setFlag(0, Value);
+ }
+ bool getInImmediateFunctionContext() const {
+ return DelayedDecltypeBinds.getFlag(1);
+ }
+ bool setInImmediateFunctionContext(bool Value) {
+ DelayedDecltypeBinds.setFlag(1, Value);
+ return Value;
+ }
+ bool getInImmediateEscalatingFunctionContext() const {
+ return DelayedDecltypeBinds.getFlag(2);
+ }
+ void setInImmediateEscalatingFunctionContext(bool Value) {
+ DelayedDecltypeBinds.setFlag(2, Value);
+ }
- bool IsCurrentlyCheckingDefaultArgumentOrInitializer = false;
+ bool getIsCurrentlyCheckingDefaultArgumentOrInitializer() const {
+ return DelayedDecltypeBinds.getFlag(3);
+ }
+ void setIsCurrentlyCheckingDefaultArgumentOrInitializer(bool Value) {
+ DelayedDecltypeBinds.setFlag(3, Value);
+ }
// We are in a constant context, but we also allow
// non constant expressions, for example for array bounds (which may be
// VLAs).
- bool InConditionallyConstantEvaluateContext = false;
+ bool getInConditionallyConstantEvaluateContext() const {
+ return DelayedDecltypeCalls.getFlag(0);
+ }
+ void setInConditionallyConstantEvaluateContext(bool Value) {
+ DelayedDecltypeCalls.setFlag(0, Value);
+ }
/// Whether we are currently in a context in which all temporaries must be
/// lifetime-extended, even if they're not bound to a reference (for
/// example, in a for-range initializer).
- bool InLifetimeExtendingContext = false;
+ bool getInLifetimeExtendingContext() const {
+ return DelayedDecltypeCalls.getFlag(1);
+ }
+ void setInLifetimeExtendingContext(bool Value) {
+ DelayedDecltypeCalls.setFlag(1, Value);
+ }
/// Whether evaluating an expression for a switch case label.
- bool IsCaseExpr = false;
+ bool getIsCaseExpr() const { return DelayedDecltypeCalls.getFlag(2); }
+ void setIsCaseExpr(bool Value) { DelayedDecltypeCalls.setFlag(2, Value); }
/// Whether we should rebuild CXXDefaultArgExpr and CXXDefaultInitExpr.
- bool RebuildDefaultArgOrDefaultInit = false;
+ bool getRebuildDefaultArgOrDefaultInit() const {
+ return DelayedDecltypeCalls.getFlag(3);
+ }
+ void setRebuildDefaultArgOrDefaultInit(bool Value) {
+ DelayedDecltypeCalls.setFlag(3, Value);
+ }
// When evaluating immediate functions in the initializer of a default
// argument or default member initializer, this is the declaration whose
@@ -6978,9 +7051,7 @@ class Sema final : public SemaBase {
ExpressionKind ExprContext)
: Context(Context), ParentCleanup(ParentCleanup),
NumCleanupObjects(NumCleanupObjects),
- ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext),
- InDiscardedStatement(false), InImmediateFunctionContext(false),
- InImmediateEscalatingFunctionContext(false) {}
+ ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext) {}
bool isUnevaluated() const {
return Context == ExpressionEvaluationContext::Unevaluated ||
@@ -7003,7 +7074,7 @@ class Sema final : public SemaBase {
bool isImmediateFunctionContext() const {
return Context == ExpressionEvaluationContext::ImmediateFunctionContext ||
(Context == ExpressionEvaluationContext::DiscardedStatement &&
- InImmediateFunctionContext) ||
+ getInImmediateFunctionContext()) ||
// C++23 [expr.const]p14:
// An expression or conversion is in an immediate function
// context if it is potentially evaluated and either:
@@ -7012,7 +7083,7 @@ class Sema final : public SemaBase {
// * its enclosing statement is enclosed by the compound-
// statement of a consteval if statement.
(Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
- InImmediateFunctionContext);
+ getInImmediateFunctionContext());
}
bool isDiscardedStatementContext() const {
@@ -7020,7 +7091,7 @@ class Sema final : public SemaBase {
((Context ==
ExpressionEvaluationContext::ImmediateFunctionContext ||
isPotentiallyEvaluated()) &&
- InDiscardedStatement);
+ getInDiscardedStatement());
}
};
@@ -8275,12 +8346,17 @@ class Sema final : public SemaBase {
/// Whether the AST is currently being rebuilt to correct immediate
/// invocations. Immediate invocation candidates and references to consteval
/// functions aren't tracked when this is set.
- bool RebuildingImmediateInvocation = false;
+ bool getRebuildingImmediateInvocation() const {
+ return SavedVTableUses.getFlag(2);
+ }
+ void setRebuildingImmediateInvocation(bool Value) {
+ SavedVTableUses.setFlag(2, Value);
+ }
bool isAlwaysConstantEvaluatedContext() const {
const ExpressionEvaluationContextRecord &Ctx = currentEvaluationContext();
return (Ctx.isConstantEvaluated() || isConstantEvaluatedOverride) &&
- !Ctx.InConditionallyConstantEvaluateContext;
+ !Ctx.getInConditionallyConstantEvaluateContext();
}
/// Determines whether we are currently in a context that
@@ -8294,18 +8370,18 @@ class Sema final : public SemaBase {
}
bool isInLifetimeExtendingContext() const {
- return currentEvaluationContext().InLifetimeExtendingContext;
+ return currentEvaluationContext().getInLifetimeExtendingContext();
}
bool needsRebuildOfDefaultArgOrInit() const {
- return currentEvaluationContext().RebuildDefaultArgOrDefaultInit;
+ return currentEvaluationContext().getRebuildDefaultArgOrDefaultInit();
}
bool isCheckingDefaultArgumentOrInitializer() const {
const ExpressionEvaluationContextRecord &Ctx = currentEvaluationContext();
return (Ctx.Context ==
ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed) ||
- Ctx.IsCurrentlyCheckingDefaultArgumentOrInitializer;
+ Ctx.getIsCurrentlyCheckingDefaultArgumentOrInitializer();
}
std::optional<ExpressionEvaluationContextRecord::InitializationContext>
@@ -8477,7 +8553,10 @@ class Sema final : public SemaBase {
/// A flag to remember whether the implicit forms of operator new and delete
/// have been declared.
- bool GlobalNewDeleteDeclared;
+ bool getGlobalNewDeleteDeclared() const { return SavedVTableUses.getFlag(3); }
+ void setGlobalNewDeleteDeclared(bool Value) {
+ SavedVTableUses.setFlag(3, Value);
+ }
/// Delete-expressions to be analyzed at the end of translation unit
///
@@ -9391,7 +9470,12 @@ class Sema final : public SemaBase {
public:
/// Tracks whether we are in a context where typo correction is
/// disabled.
- bool DisableTypoCorrection;
+ bool getDisableTypoCorrection() const {
+ return LateParsedInstantiations.getFlag(0);
+ }
+ void setDisableTypoCorrection(bool Value) {
+ LateParsedInstantiations.setFlag(0, Value);
+ }
/// The number of typos corrected by CorrectTypo.
unsigned TyposCorrected;
@@ -9914,7 +9998,12 @@ class Sema final : public SemaBase {
/// Whether we have already loaded known namespaces from an extenal
/// source.
- bool LoadedExternalKnownNamespaces;
+ bool getLoadedExternalKnownNamespaces() const {
+ return LateParsedInstantiations.getFlag(1);
+ }
+ void setLoadedExternalKnownNamespaces(bool Value) {
+ LateParsedInstantiations.setFlag(1, Value);
+ }
bool CppLookupName(LookupResult &R, Scope *S);
@@ -10131,7 +10220,12 @@ class Sema final : public SemaBase {
VisibleModuleSet VisibleModules;
/// Whether we had imported any named modules.
- bool HadImportedNamedModules = false;
+ bool getHadImportedNamedModules() const {
+ return LateParsedInstantiations.getFlag(2);
+ }
+ void setHadImportedNamedModules(bool Value) {
+ LateParsedInstantiations.setFlag(2, Value);
+ }
/// The set of instantiations we need to check if they references TU-local
/// entity from TUs. This only makes sense if we imported any named modules.
llvm::SmallVector<std::pair<FunctionDecl *, SourceLocation>>
@@ -10158,7 +10252,8 @@ class Sema final : public SemaBase {
public:
/// Whether deferrable diagnostics should be deferred.
- bool DeferDiags = false;
+ bool getDeferDiags() const { return LateParsedInstantiations.getFlag(3); }
+ void setDeferDiags(bool Value) { LateParsedInstantiations.setFlag(3, Value); }
/// RAII class to control scope of DeferDiags.
class DeferDiagsRAII {
@@ -10167,10 +10262,10 @@ class Sema final : public SemaBase {
public:
DeferDiagsRAII(Sema &S, bool DeferDiags)
- : S(S), SavedDeferDiags(S.DeferDiags) {
- S.DeferDiags = SavedDeferDiags || DeferDiags;
+ : S(S), SavedDeferDiags(S.getDeferDiags()) {
+ S.setDeferDiags(SavedDeferDiags || DeferDiags);
}
- ~DeferDiagsRAII() { S.DeferDiags = SavedDeferDiags; }
+ ~DeferDiagsRAII() { S.setDeferDiags(SavedDeferDiags); }
DeferDiagsRAII(const DeferDiagsRAII &) = delete;
DeferDiagsRAII &operator=(const DeferDiagsRAII &) = delete;
};
@@ -10179,7 +10274,12 @@ class Sema final : public SemaBase {
///
/// This flag is used to avoid building recovery call expressions
/// if Sema is already doing so, which would cause infinite recursions.
- bool IsBuildingRecoveryCallExpr;
+ bool getIsBuildingRecoveryCallExpr() const {
+ return CodeSynthesisContextLookupModules.getFlag(0);
+ }
+ void setIsBuildingRecoveryCallExpr(bool Value) {
+ CodeSynthesisContextLookupModules.setFlag(0, Value);
+ }
/// Determine whether the given New declaration is an overload of the
/// declarations in Old. This routine returns OverloadKind::Match or
@@ -12154,28 +12254,37 @@ class Sema final : public SemaBase {
struct CheckTemplateArgumentInfo {
explicit CheckTemplateArgumentInfo(bool PartialOrdering = false,
bool MatchingTTP = false)
- : PartialOrdering(PartialOrdering), MatchingTTP(MatchingTTP) {}
+ : CanonicalConverted(decltype(this->CanonicalConverted)::withFlags(
+ unsigned(PartialOrdering) | (unsigned(MatchingTTP) << 1))) {}
CheckTemplateArgumentInfo(const CheckTemplateArgumentInfo &) = delete;
CheckTemplateArgumentInfo &
operator=(const CheckTemplateArgumentInfo &) = delete;
/// The checked, converted argument will be added to the
/// end of these vectors.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ SmallVector<TemplateArgument, 4> SugaredConverted;
+ llvm::SmallVectorWithFlags<TemplateArgument, 4, 3> CanonicalConverted;
/// The check is being performed in the context of partial ordering.
- bool PartialOrdering;
+ bool getPartialOrdering() const { return CanonicalConverted.getFlag(0); }
+ void setPartialOrdering(bool Value) {
+ CanonicalConverted.setFlag(0, Value);
+ }
/// If true, assume these template arguments are
/// the injected template arguments for a template template parameter.
/// This will relax the requirement that all its possible uses are valid:
/// TTP checking is loose, and assumes that invalid uses will be diagnosed
/// during instantiation.
- bool MatchingTTP;
+ bool getMatchingTTP() const { return CanonicalConverted.getFlag(1); }
+ void setMatchingTTP(bool Value) { CanonicalConverted.setFlag(1, Value); }
/// Is set to true when, in the context of TTP matching, a pack parameter
/// matches non-pack arguments.
- bool StrictPackMatch = false;
+ bool getStrictPackMatch() const { return CanonicalConverted.getFlag(2); }
+ void setStrictPackMatch(bool Value) {
+ CanonicalConverted.setFlag(2, Value);
+ }
};
/// Check that the given template argument corresponds to the given
@@ -12256,10 +12365,9 @@ class Sema final : public SemaBase {
CheckTemplateArgumentInfo &CTAI, bool UpdateArgsWithConversions = true,
bool *ConstraintsNotSatisfied = nullptr);
- bool CheckTemplateTypeArgument(
- TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg,
- SmallVectorImpl<TemplateArgument> &SugaredConverted,
- SmallVectorImpl<TemplateArgument> &CanonicalConverted);
+ bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
+ TemplateArgumentLoc &Arg,
+ CheckTemplateArgumentInfo &CTAI);
/// Check a template argument against its corresponding
/// template type parameter.
@@ -12679,11 +12787,11 @@ class Sema final : public SemaBase {
public:
explicit TentativeAnalysisScope(Sema &SemaRef)
: SemaRef(SemaRef), Trap(SemaRef, /*ForValidityCheck=*/true),
- PrevDisableTypoCorrection(SemaRef.DisableTypoCorrection) {
- SemaRef.DisableTypoCorrection = true;
+ PrevDisableTypoCorrection(SemaRef.getDisableTypoCorrection()) {
+ SemaRef.setDisableTypoCorrection(true);
}
~TentativeAnalysisScope() {
- SemaRef.DisableTypoCorrection = PrevDisableTypoCorrection;
+ SemaRef.setDisableTypoCorrection(PrevDisableTypoCorrection);
}
TentativeAnalysisScope(const TentativeAnalysisScope &) = delete;
@@ -13212,8 +13320,9 @@ class Sema final : public SemaBase {
public:
/// A helper class for building up ExtParameterInfos.
class ExtParameterInfoBuilder {
- SmallVector<FunctionProtoType::ExtParameterInfo, 16> Infos;
- bool HasInteresting = false;
+ llvm::SmallVectorWithFlags<FunctionProtoType::ExtParameterInfo, 16> Infos;
+ bool getHasInteresting() const { return Infos.getFlag(0); }
+ void setHasInteresting(bool Value) { Infos.setFlag(0, Value); }
public:
/// Set the ExtParameterInfo for the parameter at the given index,
@@ -13223,15 +13332,15 @@ class Sema final : public SemaBase {
Infos.resize(index);
Infos.push_back(info);
- if (!HasInteresting)
- HasInteresting = (info != FunctionProtoType::ExtParameterInfo());
+ if (!getHasInteresting())
+ setHasInteresting((info != FunctionProtoType::ExtParameterInfo()));
}
/// Return a pointer (suitable for setting in an ExtProtoInfo) to the
/// ExtParameterInfo array we've built up.
const FunctionProtoType::ExtParameterInfo *
getPointerOrNull(unsigned numParams) {
- if (!HasInteresting)
+ if (!getHasInteresting())
return nullptr;
Infos.resize(numParams);
return Infos.data();
@@ -13800,7 +13909,7 @@ class Sema final : public SemaBase {
/// Extra modules inspected when performing a lookup during a template
/// instantiation. Computed lazily.
- SmallVector<Module *, 16> CodeSynthesisContextLookupModules;
+ llvm::SmallVectorWithFlags<Module *, 16> CodeSynthesisContextLookupModules;
/// Cache of additional modules that should be used for name lookup
/// within the current template instantiation. Computed lazily; use
@@ -14189,10 +14298,11 @@ class Sema final : public SemaBase {
/// Queue of implicit template instantiations that cannot be performed
/// eagerly.
- SmallVector<PendingImplicitInstantiation, 1> LateParsedInstantiations;
+ llvm::SmallVectorWithFlags<PendingImplicitInstantiation, 1, 4>
+ LateParsedInstantiations;
- SmallVector<SmallVector<VTableUse, 16>, 8> SavedVTableUses;
- SmallVector<std::deque<PendingImplicitInstantiation>, 8>
+ llvm::SmallVectorWithFlags<SmallVector<VTableUse, 16>, 8, 4> SavedVTableUses;
+ llvm::SmallVectorWithFlags<std::deque<PendingImplicitInstantiation>, 8, 4>
SavedPendingInstantiations;
/// The queue of implicit template instantiations that are required
@@ -14395,8 +14505,7 @@ class Sema final : public SemaBase {
VarTemplateSpecializationDecl *BuildVarTemplateInstantiation(
VarTemplateDecl *VarTemplate, VarDecl *FromVar,
const TemplateArgumentList *PartialSpecArgs,
- SmallVectorImpl<TemplateArgument> &Converted,
- SourceLocation PointOfInstantiation,
+ ArrayRef<TemplateArgument> Converted, SourceLocation PointOfInstantiation,
LateInstantiatedAttrVec *LateAttrs = nullptr,
LocalInstantiationScope *StartingScope = nullptr);
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index 3d62f47dfde69..eafe3a300c602 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Frontend/HLSL/SemanticSignatures.h"
#include "llvm/TargetParser/Triple.h"
@@ -265,13 +266,18 @@ class SemaHLSL : public SemaBase {
// Global declaration collected for the $Globals default constant
// buffer which will be created at the end of the translation unit.
- llvm::SmallVector<Decl *> DefaultCBufferDecls;
+ llvm::SmallVectorWithFlags<Decl *> DefaultCBufferDecls;
uint32_t ImplicitBindingNextOrderID = 0;
IdentifierInfo *RootSigOverrideIdent = nullptr;
- bool HasDeclaredAPushConstant = false;
+ bool getHasDeclaredAPushConstant() const {
+ return DefaultCBufferDecls.getFlag(0);
+ }
+ void setHasDeclaredAPushConstant(bool Value) {
+ DefaultCBufferDecls.setFlag(0, Value);
+ }
// Information about the current subtree being flattened.
struct SemanticInfo {
diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h
index 8f6041b5f00e4..9a031f60c07f0 100644
--- a/clang/include/clang/Sema/SemaInternal.h
+++ b/clang/include/clang/Sema/SemaInternal.h
@@ -19,6 +19,7 @@
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
@@ -90,20 +91,19 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer {
typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
public:
- TypoCorrectionConsumer(Sema &SemaRef,
- const DeclarationNameInfo &TypoName,
- Sema::LookupNameKind LookupKind,
- Scope *S, CXXScopeSpec *SS,
+ TypoCorrectionConsumer(Sema &SemaRef, const DeclarationNameInfo &TypoName,
+ Sema::LookupNameKind LookupKind, Scope *S,
+ CXXScopeSpec *SS,
std::unique_ptr<CorrectionCandidateCallback> CCC,
- DeclContext *MemberContext,
- bool EnteringContext)
+ DeclContext *MemberContext, bool EnteringContext)
: Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0),
SavedTCIndex(0), SemaRef(SemaRef), S(S),
SS(SS ? std::make_unique<CXXScopeSpec>(*SS) : nullptr),
CorrectionValidator(std::move(CCC)), MemberContext(MemberContext),
Result(SemaRef, TypoName, LookupKind),
Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
- EnteringContext(EnteringContext), SearchNamespaces(false) {
+ QualifiedResults(decltype(this->QualifiedResults)::withFlags(
+ unsigned(EnteringContext))) {
Result.suppressDiagnostics();
// Arrange for ValidatedCorrections[0] to always be an empty correction.
ValidatedCorrections.push_back(TypoCorrection());
@@ -315,9 +315,11 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer {
DeclContext *MemberContext;
LookupResult Result;
NamespaceSpecifierSet Namespaces;
- SmallVector<TypoCorrection, 2> QualifiedResults;
- bool EnteringContext;
- bool SearchNamespaces;
+ llvm::SmallVectorWithFlags<TypoCorrection, 2, 2> QualifiedResults;
+ bool getEnteringContext() const { return QualifiedResults.getFlag(0); }
+ void setEnteringContext(bool Value) { QualifiedResults.setFlag(0, Value); }
+ bool getSearchNamespaces() const { return QualifiedResults.getFlag(1); }
+ void setSearchNamespaces(bool Value) { QualifiedResults.setFlag(1, Value); }
};
} // end namespace clang
diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h
index 50e950e56c6ca..cf001564964e2 100644
--- a/clang/include/clang/Sema/Template.h
+++ b/clang/include/clang/Sema/Template.h
@@ -22,6 +22,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <cassert>
#include <optional>
#include <utility>
@@ -409,7 +410,7 @@ enum class TemplateSubstitutionKind : char {
LocalDeclsMap LocalDecls;
/// The set of argument packs we've allocated.
- SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
+ llvm::SmallVectorWithFlags<DeclArgumentPack *, 1, 3> ArgumentPacks;
/// The outer scope, which contains local variable
/// definitions from some other instantiation (that may not be
@@ -417,16 +418,25 @@ enum class TemplateSubstitutionKind : char {
LocalInstantiationScope *Outer;
/// Whether we have already exited this scope.
- bool Exited = false;
+ bool getExited() const { return ArgumentPacks.getFlag(0); }
+ void setExited(bool Value) { ArgumentPacks.setFlag(0, Value); }
/// Whether to combine this scope with the outer scope, such that
/// lookup will search our outer scope.
- bool CombineWithOuterScope;
+ bool getCombineWithOuterScope() const { return ArgumentPacks.getFlag(1); }
+ void setCombineWithOuterScope(bool Value) {
+ ArgumentPacks.setFlag(1, Value);
+ }
/// Whether this scope is being used to instantiate a lambda or block
/// expression, in which case it should be reused for instantiating the
/// lambda's FunctionProtoType.
- bool InstantiatingLambdaOrBlock = false;
+ bool getInstantiatingLambdaOrBlock() const {
+ return ArgumentPacks.getFlag(2);
+ }
+ void setInstantiatingLambdaOrBlock(bool Value) {
+ ArgumentPacks.setFlag(2, Value);
+ }
/// If non-NULL, the template parameter pack that has been
/// partially substituted per C++0x [temp.arg.explicit]p9.
@@ -444,9 +454,10 @@ enum class TemplateSubstitutionKind : char {
public:
LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false,
bool InstantiatingLambdaOrBlock = false)
- : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
- CombineWithOuterScope(CombineWithOuterScope),
- InstantiatingLambdaOrBlock(InstantiatingLambdaOrBlock) {
+ : SemaRef(SemaRef), ArgumentPacks(decltype(ArgumentPacks)::withFlags(
+ (unsigned(CombineWithOuterScope) << 1) |
+ (unsigned(InstantiatingLambdaOrBlock) << 2))),
+ Outer(SemaRef.CurrentInstantiationScope) {
SemaRef.CurrentInstantiationScope = this;
}
@@ -462,14 +473,14 @@ enum class TemplateSubstitutionKind : char {
/// Exit this local instantiation scope early.
void Exit() {
- if (Exited)
+ if (getExited())
return;
for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
delete ArgumentPacks[I];
SemaRef.CurrentInstantiationScope = Outer;
- Exited = true;
+ setExited(true);
}
/// Clone this scope, and all outer scopes, down to the given
@@ -482,7 +493,7 @@ enum class TemplateSubstitutionKind : char {
LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope;
LocalInstantiationScope *newScope =
- new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
+ new LocalInstantiationScope(SemaRef, getCombineWithOuterScope());
newScope->Outer = nullptr;
if (Outer)
@@ -580,7 +591,7 @@ enum class TemplateSubstitutionKind : char {
bool isLocalPackExpansion(const Decl *D);
/// Determine whether this scope is for instantiating a lambda or block.
- bool isLambdaOrBlock() const { return InstantiatingLambdaOrBlock; }
+ bool isLambdaOrBlock() const { return getInstantiatingLambdaOrBlock(); }
};
class TemplateDeclInstantiator
@@ -593,7 +604,12 @@ enum class TemplateSubstitutionKind : char {
Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
LocalInstantiationScope *StartingScope = nullptr;
// Whether to evaluate the C++20 constraints or simply substitute into them.
- bool EvaluateConstraints = true;
+ bool getEvaluateConstraintsFlag() const {
+ return !OutOfLineVarPartialSpecs.getFlag(0);
+ }
+ void setEvaluateConstraintsFlag(bool Value) {
+ OutOfLineVarPartialSpecs.setFlag(0, !Value);
+ }
/// A list of out-of-line class template partial
/// specializations that will need to be instantiated after the
@@ -607,7 +623,7 @@ enum class TemplateSubstitutionKind : char {
/// specializations that will need to be instantiated after the
/// enclosing variable's instantiation is complete.
/// FIXME: Verify that this is needed.
- SmallVector<
+ llvm::SmallVectorWithFlags<
std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 1>
OutOfLineVarPartialSpecs;
@@ -617,12 +633,8 @@ enum class TemplateSubstitutionKind : char {
: SemaRef(SemaRef), SubstIndex(SemaRef, SemaRef.ArgPackSubstIndex),
Owner(Owner), TemplateArgs(TemplateArgs) {}
- void setEvaluateConstraints(bool B) {
- EvaluateConstraints = B;
- }
- bool getEvaluateConstraints() {
- return EvaluateConstraints;
- }
+ void setEvaluateConstraints(bool B) { setEvaluateConstraintsFlag(B); }
+ bool getEvaluateConstraints() { return getEvaluateConstraintsFlag(); }
// Define all the decl visitors using DeclNodes.inc
#define DECL(DERIVED, BASE) \
diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h
index dd9fe46c9bf8a..8b34eb9a6e413 100644
--- a/clang/include/clang/Sema/TemplateDeduction.h
+++ b/clang/include/clang/Sema/TemplateDeduction.h
@@ -14,15 +14,16 @@
#ifndef LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
#define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H
-#include "clang/Sema/Ownership.h"
-#include "clang/Sema/SemaConcept.h"
#include "clang/AST/ASTConcept.h"
#include "clang/AST/DeclAccessPair.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/Ownership.h"
+#include "clang/Sema/SemaConcept.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <cassert>
#include <cstddef>
#include <optional>
@@ -351,13 +352,14 @@ struct TemplateSpecCandidate {
/// TODO: In the future, we may need to unify/generalize this with
/// OverloadCandidateSet.
class TemplateSpecCandidateSet {
- SmallVector<TemplateSpecCandidate, 16> Candidates;
+ llvm::SmallVectorWithFlags<TemplateSpecCandidate, 16> Candidates;
SourceLocation Loc;
// Stores whether we're taking the address of these candidates. This helps us
// produce better error messages when dealing with the pass_object_size
// attribute on parameters.
- bool ForTakingAddress;
+ bool getForTakingAddress() const { return Candidates.getFlag(0); }
+ void setForTakingAddress(bool Value) { Candidates.setFlag(0, Value); }
TemplateSpecCandidateSetKind CandidateSetKind;
@@ -367,8 +369,8 @@ class TemplateSpecCandidateSet {
TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false,
TemplateSpecCandidateSetKind CandidateSetKind =
TemplateSpecCandidateSetKind::Normal)
- : Loc(Loc), ForTakingAddress(ForTakingAddress),
- CandidateSetKind(CandidateSetKind) {}
+ : Candidates(decltype(Candidates)::withFlags(unsigned(ForTakingAddress))),
+ Loc(Loc), CandidateSetKind(CandidateSetKind) {}
TemplateSpecCandidateSet(const TemplateSpecCandidateSet &) = delete;
TemplateSpecCandidateSet &
operator=(const TemplateSpecCandidateSet &) = delete;
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 275383d40cf80..b8a58fcfe79d0 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -44,6 +44,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
@@ -484,7 +485,12 @@ class ASTReader : public ExternalPreprocessorSource,
/// The receiver of deserialization events.
ASTDeserializationListener *DeserializationListener = nullptr;
- bool OwnsDeserializationListener = false;
+ bool getOwnsDeserializationListener() const {
+ return CommentsCursors.getFlag(0);
+ }
+ void setOwnsDeserializationListener(bool Value) {
+ CommentsCursors.setFlag(0, Value);
+ }
SourceManager &SourceMgr;
FileManager &FileMgr;
@@ -1087,29 +1093,59 @@ class ASTReader : public ExternalPreprocessorSource,
DisableValidationForModuleKind DisableValidationKind;
/// Whether to accept an AST file with compiler errors.
- bool AllowASTWithCompilerErrors;
+ bool getAllowASTWithCompilerErrors() const {
+ return CommentsCursors.getFlag(1);
+ }
+ void setAllowASTWithCompilerErrors(bool Value) {
+ CommentsCursors.setFlag(1, Value);
+ }
/// Whether to accept an AST file that has a different configuration
/// from the current compiler instance.
- bool AllowConfigurationMismatch;
+ bool getAllowConfigurationMismatch() const {
+ return CommentsCursors.getFlag(2);
+ }
+ void setAllowConfigurationMismatch(bool Value) {
+ CommentsCursors.setFlag(2, Value);
+ }
/// Whether to validate system input files.
- bool ValidateSystemInputs;
+ bool getValidateSystemInputs() const { return CommentsCursors.getFlag(3); }
+ void setValidateSystemInputs(bool Value) {
+ CommentsCursors.setFlag(3, Value);
+ }
/// Whether to force the validation of user input files.
- bool ForceValidateUserInputs;
+ bool getForceValidateUserInputs() const {
+ return PreloadedDeclIDs.getFlag(0);
+ }
+ void setForceValidateUserInputs(bool Value) {
+ PreloadedDeclIDs.setFlag(0, Value);
+ }
/// Whether validate headers and module maps using hash based on contents.
- bool ValidateASTInputFilesContent;
+ bool getValidateASTInputFilesContent() const {
+ return PreloadedDeclIDs.getFlag(1);
+ }
+ void setValidateASTInputFilesContent(bool Value) {
+ PreloadedDeclIDs.setFlag(1, Value);
+ }
/// Whether we are allowed to use the global module index.
- bool UseGlobalIndex;
+ bool getUseGlobalIndex() const { return PreloadedDeclIDs.getFlag(2); }
+ void setUseGlobalIndex(bool Value) { PreloadedDeclIDs.setFlag(2, Value); }
/// Whether we have tried loading the global module index yet.
- bool TriedLoadingGlobalIndex = false;
+ bool getTriedLoadingGlobalIndex() const {
+ return PreloadedDeclIDs.getFlag(3);
+ }
+ void setTriedLoadingGlobalIndex(bool Value) {
+ PreloadedDeclIDs.setFlag(3, Value);
+ }
///Whether we are currently processing update records.
- bool ProcessingUpdateRecords = false;
+ bool getProcessingUpdateRecords() const { return StmtStack.getFlag(0); }
+ void setProcessingUpdateRecords(bool Value) { StmtStack.setFlag(0, Value); }
using SwitchCaseMapTy = llvm::DenseMap<unsigned, SwitchCase *>;
@@ -1197,7 +1233,8 @@ class ASTReader : public ExternalPreprocessorSource,
/// "interesting" decls to the consumer inside FinishedDeserializing().
/// This is used as a guard to avoid recursively entering the process of
/// passing decls to consumer.
- bool CanPassDeclsToConsumer = true;
+ bool getCanPassDeclsToConsumer() const { return !StmtStack.getFlag(1); }
+ void setCanPassDeclsToConsumer(bool Value) { StmtStack.setFlag(1, !Value); }
/// The set of identifiers that were read while the AST reader was
/// (recursively) loading declarations.
@@ -1354,7 +1391,7 @@ class ASTReader : public ExternalPreprocessorSource,
llvm::DenseMap<RecordDecl *, RecordDecl *> RecordDefinitions;
/// When reading a Stmt tree, Stmt operands are placed in this stack.
- SmallVector<Stmt *, 16> StmtStack;
+ llvm::SmallVectorWithFlags<Stmt *, 16, 2> StmtStack;
/// What kind of records we are reading.
enum ReadingKind {
@@ -1387,14 +1424,16 @@ class ASTReader : public ExternalPreprocessorSource,
public:
ProcessingUpdatesRAIIObj(ASTReader &reader)
- : Reader(reader), PrevState(Reader.ProcessingUpdateRecords) {
- Reader.ProcessingUpdateRecords = true;
+ : Reader(reader), PrevState(Reader.getProcessingUpdateRecords()) {
+ Reader.setProcessingUpdateRecords(true);
}
ProcessingUpdatesRAIIObj(const ProcessingUpdatesRAIIObj &) = delete;
ProcessingUpdatesRAIIObj &
operator=(const ProcessingUpdatesRAIIObj &) = delete;
- ~ProcessingUpdatesRAIIObj() { Reader.ProcessingUpdateRecords = PrevState; }
+ ~ProcessingUpdatesRAIIObj() {
+ Reader.setProcessingUpdateRecords(PrevState);
+ }
};
/// Suggested contents of the predefines buffer, after this
@@ -1952,7 +1991,7 @@ class ASTReader : public ExternalPreprocessorSource,
GlobalModuleIndex *getGlobalIndex() { return GlobalIndex.get(); }
/// Reset reader for a reload try.
- void resetForReload() { TriedLoadingGlobalIndex = false; }
+ void resetForReload() { setTriedLoadingGlobalIndex(false); }
/// Attempts to load the global index.
///
@@ -2622,7 +2661,7 @@ class ASTReader : public ExternalPreprocessorSource,
// Contains the IDs for declarations that were requested before we have
// access to a Sema object.
- SmallVector<GlobalDeclID, 16> PreloadedDeclIDs;
+ llvm::SmallVectorWithFlags<GlobalDeclID, 16, 4> PreloadedDeclIDs;
/// Retrieve the semantic analysis object used to analyze the
/// translation unit in which the precompiled header is being
@@ -2648,8 +2687,9 @@ class ASTReader : public ExternalPreprocessorSource,
void ClearSwitchCaseIDs();
/// Cursors for comments blocks.
- SmallVector<std::pair<llvm::BitstreamCursor,
- serialization::ModuleFile *>, 8> CommentsCursors;
+ llvm::SmallVectorWithFlags<
+ std::pair<llvm::BitstreamCursor, serialization::ModuleFile *>, 8, 4>
+ CommentsCursors;
/// Loads comments ranges.
void ReadComments() override;
@@ -2672,7 +2712,7 @@ class ASTReader : public ExternalPreprocessorSource,
void visitTopLevelModuleMaps(serialization::ModuleFile &MF,
llvm::function_ref<void(FileEntryRef)> Visitor);
- bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
+ bool isProcessingUpdateRecords() { return getProcessingUpdateRecords(); }
};
/// A simple helper class to unpack an integer to bits and consuming
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index 576eb86395929..8bf3d54839a29 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -32,6 +32,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitstream/BitstreamWriter.h"
#include <cassert>
@@ -157,27 +158,45 @@ class ASTWriter : public ASTDeserializationListener,
/// module file. This is the case for files implicitly written to the
/// module cache, where we need the timestamps to determine if the module
/// file is up to date, but not otherwise.
- bool IncludeTimestamps;
+ bool getIncludeTimestamps() const {
+ return PendingEmittingVTables.getFlag(0);
+ }
+ void setIncludeTimestamps(bool Value) {
+ PendingEmittingVTables.setFlag(0, Value);
+ }
/// Indicates whether the AST file being written is an implicit module.
/// If that's the case, we may be able to skip writing some information that
/// are guaranteed to be the same in the importer by the context hash.
- bool BuildingImplicitModule = false;
+ bool getBuildingImplicitModule() const {
+ return PendingEmittingVTables.getFlag(1);
+ }
+ void setBuildingImplicitModule(bool Value) {
+ PendingEmittingVTables.setFlag(1, Value);
+ }
/// Indicates when the AST writing is actively performing
/// serialization, rather than just queueing updates.
- bool WritingAST = false;
+ bool getWritingAST() const { return PendingEmittingVTables.getFlag(2); }
+ void setWritingAST(bool Value) { PendingEmittingVTables.setFlag(2, Value); }
/// Indicates that we are done serializing the collection of decls
/// and types to emit.
- bool DoneWritingDeclsAndTypes = false;
+ bool getDoneWritingDeclsAndTypesFlag() const {
+ return PendingEmittingVTables.getFlag(3);
+ }
+ void setDoneWritingDeclsAndTypesFlag(bool Value) {
+ PendingEmittingVTables.setFlag(3, Value);
+ }
/// Indicates that the AST contained compiler errors.
- bool ASTHasCompilerErrors = false;
+ bool getASTHasCompilerErrors() const { return Redeclarations.getFlag(0); }
+ void setASTHasCompilerErrors(bool Value) { Redeclarations.setFlag(0, Value); }
/// Indicates that we're going to generate the reduced BMI for C++20
/// named modules.
- bool GeneratingReducedBMI = false;
+ bool getGeneratingReducedBMI() const { return Redeclarations.getFlag(1); }
+ void setGeneratingReducedBMI(bool Value) { Redeclarations.setFlag(1, Value); }
/// Mapping from input file entries to the index into the
/// offset table where information about that input file is stored.
@@ -491,7 +510,7 @@ class ASTWriter : public ASTDeserializationListener,
/// The set of declarations that may have redeclaration chains that
/// need to be serialized.
- llvm::SmallVector<const Decl *, 16> Redeclarations;
+ llvm::SmallVectorWithFlags<const Decl *, 16, 2> Redeclarations;
/// A cache of the first local declaration for "interesting"
/// redeclaration chains.
@@ -545,7 +564,11 @@ class ASTWriter : public ASTDeserializationListener,
/// A list of classes in named modules which need to emit the VTable in
/// the corresponding object file.
- llvm::SmallVector<CXXRecordDecl *> PendingEmittingVTables;
+ llvm::SmallVectorWithFlags<
+ CXXRecordDecl *,
+ llvm::CalculateSmallVectorDefaultInlinedElements<CXXRecordDecl *>::value,
+ 4>
+ PendingEmittingVTables;
/// Computes input files that didn't affect compilation of the current module,
/// and initializes data structures necessary for leaving those files out
@@ -949,9 +972,11 @@ class ASTWriter : public ASTDeserializationListener,
return WritingModule && WritingModule->isHeaderUnit();
}
- bool isGeneratingReducedBMI() const { return GeneratingReducedBMI; }
+ bool isGeneratingReducedBMI() const { return getGeneratingReducedBMI(); }
- bool getDoneWritingDeclsAndTypes() const { return DoneWritingDeclsAndTypes; }
+ bool getDoneWritingDeclsAndTypes() const {
+ return getDoneWritingDeclsAndTypesFlag();
+ }
bool isDeclPredefined(const Decl *D) const {
return PredefinedDecls.count(D);
@@ -1036,9 +1061,9 @@ class PCHGenerator : public SemaConsumer {
protected:
ASTWriter &getWriter() { return Writer; }
const ASTWriter &getWriter() const { return Writer; }
- SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
+ llvm::SmallVectorWithFlagsImpl<char> &getPCH() const { return Buffer->Data; }
- bool isComplete() const { return Buffer->IsComplete; }
+ bool isComplete() const { return Buffer->getIsComplete(); }
PCHBuffer *getBufferPtr() { return Buffer.get(); }
StringRef getOutputFile() const { return OutputFile; }
DiagnosticsEngine &getDiagnostics() const;
@@ -1061,7 +1086,7 @@ class PCHGenerator : public SemaConsumer {
void HandleVTable(CXXRecordDecl *RD) override { Writer.handleVTable(RD); }
ASTMutationListener *GetASTMutationListener() override;
ASTDeserializationListener *GetASTDeserializationListener() override;
- bool hasEmittedPCH() const { return Buffer->IsComplete; }
+ bool hasEmittedPCH() const { return Buffer->getIsComplete(); }
};
class CXX20ModulesGenerator : public PCHGenerator {
diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h
index c6353d31d4e54..b903ed6eb7f80 100644
--- a/clang/include/clang/Serialization/ModuleFile.h
+++ b/clang/include/clang/Serialization/ModuleFile.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Support/Endian.h"
@@ -208,16 +209,24 @@ class ModuleFile {
std::vector<std::string> DirectoryDependencies;
/// Whether this precompiled header is a relocatable PCH file.
- bool RelocatablePCH = false;
+ bool getRelocatablePCH() const { return TransitiveImports.getFlag(0); }
+ void setRelocatablePCH(bool Value) { TransitiveImports.setFlag(0, Value); }
/// Whether this module file is a standard C++ module.
- bool StandardCXXModule = false;
+ bool getStandardCXXModule() const { return TransitiveImports.getFlag(1); }
+ void setStandardCXXModule(bool Value) { TransitiveImports.setFlag(1, Value); }
/// Whether timestamps are included in this module file.
- bool HasTimestamps = false;
+ bool getHasTimestamps() const { return TransitiveImports.getFlag(2); }
+ void setHasTimestamps(bool Value) { TransitiveImports.setFlag(2, Value); }
/// Whether the top-level module has been read from the AST file.
- bool DidReadTopLevelSubmodule = false;
+ bool getDidReadTopLevelSubmodule() const {
+ return TransitiveImports.getFlag(3);
+ }
+ void setDidReadTopLevelSubmodule(bool Value) {
+ TransitiveImports.setFlag(3, Value);
+ }
/// Size of the module file.
off_t Size = 0;
@@ -563,7 +572,7 @@ class ModuleFile {
/// the same order with that module file manager when we write
/// the current module file. The value of the member will be initialized
/// in `ASTReader::ReadModuleOffsetMap`.
- llvm::SmallVector<ModuleFile *, 16> TransitiveImports;
+ llvm::SmallVectorWithFlags<ModuleFile *, 16, 4> TransitiveImports;
/// Determine whether this module was directly imported at
/// any point during translation.
diff --git a/clang/include/clang/Serialization/PCHContainerOperations.h b/clang/include/clang/Serialization/PCHContainerOperations.h
index c9a7e334ce6eb..3870a283cb9bb 100644
--- a/clang/include/clang/Serialization/PCHContainerOperations.h
+++ b/clang/include/clang/Serialization/PCHContainerOperations.h
@@ -11,6 +11,7 @@
#include "clang/Basic/Module.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBufferRef.h"
#include <memory>
@@ -26,8 +27,9 @@ class CompilerInstance;
struct PCHBuffer {
ASTFileSignature Signature;
- llvm::SmallVector<char, 0> Data;
- bool IsComplete;
+ llvm::SmallVectorWithFlags<char, 0> Data;
+ bool getIsComplete() const { return Data.getFlag(0); }
+ void setIsComplete(bool Value) { Data.setFlag(0, Value); }
};
/// This abstract interface provides operations for creating
diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 51c54151ac07b..17f17c6b0a4e9 100644
--- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -31,6 +31,7 @@
#include "llvm/ADT/ImmutableSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -329,7 +330,7 @@ class PathSensitiveBugReport : public BugReport {
/// A set of custom visitors which generate "event" diagnostics at
/// interesting points in the path.
- VisitorList Callbacks;
+ llvm::SmallVectorWithFlagsFor<VisitorList, 1> Callbacks;
/// Used for ensuring the visitors are only added once.
llvm::FoldingSet<BugReporterVisitor> CallbacksSet;
@@ -337,7 +338,8 @@ class PathSensitiveBugReport : public BugReport {
/// When set, this flag disables all callstack pruning from a diagnostic
/// path. This is useful for some reports that want maximum fidelty
/// when reporting an issue.
- bool DoNotPrunePath = false;
+ bool getDoNotPrunePath() const { return Callbacks.getFlag(0); }
+ void setDoNotPrunePath(bool Value) { Callbacks.setFlag(0, Value); }
/// Used to track unique reasons why a bug report might be invalid.
///
@@ -408,10 +410,10 @@ class PathSensitiveBugReport : public BugReport {
/// Indicates whether or not any path pruning should take place
/// when generating a PathDiagnostic from this BugReport.
- bool shouldPrunePath() const { return !DoNotPrunePath; }
+ bool shouldPrunePath() const { return !getDoNotPrunePath(); }
/// Disable all path pruning when generating a PathDiagnostic.
- void disablePathPruning() { DoNotPrunePath = true; }
+ void disablePathPruning() { setDoNotPrunePath(true); }
/// Get the location on which the report should be uniqued.
PathDiagnosticLocation getUniqueingLocation() const override {
diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 46e648c6b7d90..4ee0a415cb82c 100644
--- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include <vector>
@@ -613,7 +614,7 @@ class CheckerManager {
template <typename EVENT>
void _registerDispatcherForEvent() {
EventInfo &info = Events[&EVENT::Tag];
- info.HasDispatcher = true;
+ info.setHasDispatcher(true);
}
template <typename EVENT>
@@ -706,8 +707,9 @@ class CheckerManager {
std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
struct EventInfo {
- SmallVector<CheckEventFunc, 4> Checkers;
- bool HasDispatcher = false;
+ llvm::SmallVectorWithFlags<CheckEventFunc, 4> Checkers;
+ bool getHasDispatcher() const { return Checkers.getFlag(0); }
+ void setHasDispatcher(bool Value) { Checkers.setFlag(0, Value); }
EventInfo() = default;
};
diff --git a/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h b/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
index 84b1d19e52c8a..ca1b586b311cd 100644
--- a/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
+++ b/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
@@ -13,6 +13,7 @@
#include "clang/Tooling/Inclusions/IncludeStyle.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Regex.h"
#include <list>
@@ -43,9 +44,10 @@ class IncludeCategoryManager {
bool isMainHeader(StringRef IncludeName) const;
const IncludeStyle Style;
- bool IsMainFile;
+ bool getIsMainFile() const { return CategoryRegexs.getFlag(0); }
+ void setIsMainFile(bool Value) { CategoryRegexs.setFlag(0, Value); }
std::string FileName;
- SmallVector<llvm::Regex, 4> CategoryRegexs;
+ llvm::SmallVectorWithFlags<llvm::Regex, 4> CategoryRegexs;
};
enum class IncludeDirective { Include, Import };
diff --git a/clang/include/clang/Tooling/Refactoring/ASTSelection.h b/clang/include/clang/Tooling/Refactoring/ASTSelection.h
index ae778acb5e017..e38cba8cd2acb 100644
--- a/clang/include/clang/Tooling/Refactoring/ASTSelection.h
+++ b/clang/include/clang/Tooling/Refactoring/ASTSelection.h
@@ -13,6 +13,7 @@
#include "clang/AST/Stmt.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
#include <vector>
@@ -103,13 +104,13 @@ class CodeRangeASTSelection {
/// Returns the number of selected statements.
size_t size() const {
- if (!AreChildrenSelected)
+ if (!getAreChildrenSelected())
return 1;
return SelectedNode.get().Children.size();
}
const Stmt *operator[](size_t I) const {
- if (!AreChildrenSelected) {
+ if (!getAreChildrenSelected()) {
assert(I == 0 && "Invalid index");
return SelectedNode.get().Node.get<Stmt>();
}
@@ -138,16 +139,18 @@ class CodeRangeASTSelection {
CodeRangeASTSelection(SelectedASTNode::ReferenceType SelectedNode,
ArrayRef<SelectedASTNode::ReferenceType> Parents,
bool AreChildrenSelected)
- : SelectedNode(SelectedNode), Parents(Parents),
- AreChildrenSelected(AreChildrenSelected) {}
+ : SelectedNode(SelectedNode),
+ Parents(decltype(this->Parents)::withFlags(
+ unsigned(AreChildrenSelected), Parents)) {}
/// The reference to the selected node (or reference to the selected
/// child nodes).
SelectedASTNode::ReferenceType SelectedNode;
/// The parent hierarchy (top to bottom) for the selected noe.
- llvm::SmallVector<SelectedASTNode::ReferenceType, 8> Parents;
+ llvm::SmallVectorWithFlags<SelectedASTNode::ReferenceType, 8> Parents;
/// True only when the children of the selected node are actually selected.
- bool AreChildrenSelected;
+ bool getAreChildrenSelected() const { return Parents.getFlag(0); }
+ void setAreChildrenSelected(bool Value) { Parents.setFlag(0, Value); }
};
} // end namespace tooling
diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp
index 5c1bb41d804e9..0009e88b4b678 100644
--- a/clang/lib/APINotes/APINotesManager.cpp
+++ b/clang/lib/APINotes/APINotesManager.cpp
@@ -210,7 +210,7 @@ static void checkPrivateAPINotesName(DiagnosticsEngine &Diags,
return;
unsigned DiagID = diag::warn_apinotes_private_case;
- if (M->IsSystem)
+ if (M->getIsSystem())
DiagID = diag::warn_apinotes_private_case_system;
Diags.Report(SourceLocation(), DiagID) << M->Name << RealFileName;
@@ -220,7 +220,7 @@ static void checkPrivateAPINotesName(DiagnosticsEngine &Diags,
/// private module map
static bool hasPrivateSubmodules(const Module *M) {
return llvm::any_of(M->submodules(), [](const Module *Submodule) {
- return Submodule->ModuleMapIsPrivate;
+ return Submodule->getModuleMapIsPrivate();
});
}
@@ -248,7 +248,7 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule,
APINotes.push_back(*File);
};
- if (M->IsFramework) {
+ if (M->getIsFramework()) {
// For frameworks, we search in the "Headers" or "PrivateHeaders"
// subdirectory.
//
@@ -260,7 +260,7 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule,
// the word "Private" in it in practice)
llvm::SmallString<128> Path(M->Directory->getName());
- if (!M->ModuleMapIsPrivate) {
+ if (!M->getModuleMapIsPrivate()) {
unsigned PathLen = Path.size();
llvm::sys::path::append(Path, "Headers");
@@ -270,11 +270,11 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule,
Path.resize(PathLen);
}
- if (M->ModuleMapIsPrivate || hasPrivateSubmodules(M)) {
+ if (M->getModuleMapIsPrivate() || hasPrivateSubmodules(M)) {
llvm::sys::path::append(Path, "PrivateHeaders");
if (auto PrivateAPINotesDir = FM.getOptionalDirectoryRef(Path))
tryAPINotes(*PrivateAPINotesDir,
- /*wantPublic=*/M->ModuleMapIsPrivate);
+ /*wantPublic=*/M->getModuleMapIsPrivate());
}
} else {
// Public modules:
@@ -284,7 +284,7 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule,
// - Bar.apinotes (except that 'Bar' probably already has the word
// "Private" in it in practice)
tryAPINotes(*M->Directory, /*wantPublic=*/true);
- if (!M->ModuleMapIsPrivate && hasPrivateSubmodules(M))
+ if (!M->getModuleMapIsPrivate() && hasPrivateSubmodules(M))
tryAPINotes(*M->Directory, /*wantPublic=*/false);
}
diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index 2b04821a157da..362d6f51f16cb 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -44,8 +44,8 @@ CreateUnsatisfiedConstraintRecord(const ASTContext &C,
ASTConstraintSatisfaction::ASTConstraintSatisfaction(
const ASTContext &C, const ConstraintSatisfaction &Satisfaction)
: NumRecords{Satisfaction.Details.size()},
- IsSatisfied{Satisfaction.IsSatisfied}, ContainsErrors{
- Satisfaction.ContainsErrors} {
+ IsSatisfied{Satisfaction.isSatisfied()},
+ ContainsErrors{Satisfaction.containsErrors()} {
for (unsigned I = 0; I < NumRecords; ++I)
CreateUnsatisfiedConstraintRecord(C, Satisfaction.Details[I],
getTrailingObjects() + I);
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index ed22919b7a70b..9954f1f7a6a09 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -333,9 +333,9 @@ RawComment *ASTContext::getRawCommentNoCache(RawCommentLookupKey Key) const {
if (Loc.isInvalid() || !Loc.isFileID())
continue;
- if (ExternalSource && !CommentsLoaded) {
+ if (ExternalSource && !getCommentsLoaded()) {
ExternalSource->ReadComments();
- CommentsLoaded = true;
+ setCommentsLoaded(true);
}
if (Comments.empty())
@@ -1281,7 +1281,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
this->AuxTarget = AuxTarget;
ABI.reset(createCXXABI(Target));
- AddrSpaceMapMangling = isAddrSpaceMapManglingEnabled(Target, LangOpts);
+ setAddrSpaceMapMangling(isAddrSpaceMapManglingEnabled(Target, LangOpts));
// C99 6.2.5p19.
InitBuiltinType(VoidTy, BuiltinType::Void);
@@ -5277,7 +5277,7 @@ QualType ASTContext::getFunctionTypeInternal(
if (!Unique)
FunctionProtoTypes.insert(FTP, Token);
if (!EPI.FunctionEffects.empty())
- AnyFunctionEffects = true;
+ setAnyFunctionEffects(true);
return QualType(FTP, 0);
}
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4c296b6829b1b..b3fbf25efb345 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1076,9 +1076,9 @@ StringRef ASTNodeImporter::ImportASTStringRef(StringRef FromStr) {
Error ASTNodeImporter::ImportConstraintSatisfaction(
const ASTConstraintSatisfaction &FromSat, ConstraintSatisfaction &ToSat) {
- ToSat.IsSatisfied = FromSat.IsSatisfied;
- ToSat.ContainsErrors = FromSat.ContainsErrors;
- if (!ToSat.IsSatisfied) {
+ ToSat.setIsSatisfied(FromSat.IsSatisfied);
+ ToSat.setContainsErrors(FromSat.ContainsErrors);
+ if (!ToSat.isSatisfied()) {
for (auto Record = FromSat.begin(); Record != FromSat.end(); ++Record) {
if (const Expr *E = dyn_cast<const Expr *>(*Record)) {
ExpectedExpr ToSecondExpr = import(E);
diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp
index 7272ad0de9a2c..ce43f611d5e39 100644
--- a/clang/lib/AST/AttrImpl.cpp
+++ b/clang/lib/AST/AttrImpl.cpp
@@ -241,7 +241,7 @@ void OMPDeclareVariantAttr::printPrettyPragma(
OS << "interop(";
if (!I->Prefs.empty()) {
OS << "prefer_type(";
- if (I->HasPreferAttrs) {
+ if (I->hasPreferAttrs()) {
StringRef Sep = "";
for (const auto &P : I->Prefs) {
OS << Sep << "{";
diff --git a/clang/lib/AST/Availability.cpp b/clang/lib/AST/Availability.cpp
index cd9152745826f..6059723a09746 100644
--- a/clang/lib/AST/Availability.cpp
+++ b/clang/lib/AST/Availability.cpp
@@ -15,13 +15,24 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace {
/// Represents the availability of a symbol across platforms.
struct AvailabilitySet {
- bool UnconditionallyDeprecated = false;
- bool UnconditionallyUnavailable = false;
+ bool getUnconditionallyDeprecated() const {
+ return Availabilities.getFlag(0);
+ }
+ void setUnconditionallyDeprecated(bool Value) {
+ Availabilities.setFlag(0, Value);
+ }
+ bool getUnconditionallyUnavailable() const {
+ return Availabilities.getFlag(1);
+ }
+ void setUnconditionallyUnavailable(bool Value) {
+ Availabilities.setFlag(1, Value);
+ }
void insert(clang::AvailabilityInfo &&Availability) {
auto *Found = getForPlatform(Availability.Domain);
@@ -40,7 +51,11 @@ struct AvailabilitySet {
}
private:
- llvm::SmallVector<clang::AvailabilityInfo> Availabilities;
+ llvm::SmallVectorWithFlags<clang::AvailabilityInfo,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ clang::AvailabilityInfo>::value,
+ 2>
+ Availabilities;
};
static void createInfoForDecl(const clang::Decl *Decl,
@@ -57,11 +72,11 @@ static void createInfoForDecl(const clang::Decl *Decl,
if (const auto *A = RD->getAttr<clang::UnavailableAttr>())
if (!A->isImplicit())
- Availabilities.UnconditionallyUnavailable = true;
+ Availabilities.setUnconditionallyUnavailable(true);
if (const auto *A = RD->getAttr<clang::DeprecatedAttr>())
if (!A->isImplicit())
- Availabilities.UnconditionallyDeprecated = true;
+ Availabilities.setUnconditionallyDeprecated(true);
}
}
@@ -106,15 +121,18 @@ AvailabilityInfo AvailabilityInfo::createFromDecl(const Decl *D) {
if (auto *Avail = Availabilities.getForPlatform(
D->getASTContext().getTargetInfo().getPlatformName())) {
- Avail->UnconditionallyDeprecated = Availabilities.UnconditionallyDeprecated;
+ Avail->UnconditionallyDeprecated =
+ Availabilities.getUnconditionallyDeprecated();
Avail->UnconditionallyUnavailable =
- Availabilities.UnconditionallyUnavailable;
+ Availabilities.getUnconditionallyUnavailable();
return std::move(*Avail);
}
AvailabilityInfo Avail;
- Avail.UnconditionallyDeprecated = Availabilities.UnconditionallyDeprecated;
- Avail.UnconditionallyUnavailable = Availabilities.UnconditionallyUnavailable;
+ Avail.UnconditionallyDeprecated =
+ Availabilities.getUnconditionallyDeprecated();
+ Avail.UnconditionallyUnavailable =
+ Availabilities.getUnconditionallyUnavailable();
return Avail;
}
diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp
index b57ace795fa77..0a498daa8365b 100644
--- a/clang/lib/AST/ByteCode/Disasm.cpp
+++ b/clang/lib/AST/ByteCode/Disasm.cpp
@@ -27,6 +27,7 @@
#include "clang/AST/ASTDumperUtils.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/FormatVariadic.h"
@@ -164,9 +165,14 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS,
struct OpText {
size_t Addr;
std::string Op;
- bool IsJump;
- bool CurrentOp = false;
- llvm::SmallVector<std::string> Args;
+ bool getIsJump() const { return Args.getFlag(0); }
+ void setIsJump(bool Value) { Args.setFlag(0, Value); }
+ bool getCurrentOp() const { return Args.getFlag(1); }
+ void setCurrentOp(bool Value) { Args.setFlag(1, Value); }
+ llvm::SmallVectorWithFlags<
+ std::string,
+ llvm::CalculateSmallVectorDefaultInlinedElements<std::string>::value, 2>
+ Args;
};
auto PrintName = [](const char *Name) -> std::string {
@@ -182,8 +188,8 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS,
OpText Text;
auto Op = PC.read<Opcode>();
Text.Addr = Addr;
- Text.IsJump = isJumpOpcode(Op);
- Text.CurrentOp = (PC == OpPC);
+ Text.setIsJump(isJumpOpcode(Op));
+ Text.setCurrentOp((PC == OpPC));
switch (Op) {
#define GET_DISASM
#include "Opcodes.inc"
@@ -201,7 +207,7 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS,
};
llvm::SmallVector<JmpData> Jumps;
for (auto &Text : Code) {
- if (Text.IsJump)
+ if (Text.getIsJump())
Jumps.push_back({Text.Addr, Text.Addr + std::stoi(Text.Args[0]) +
align(sizeof(Opcode)) +
align(sizeof(int32_t))});
@@ -215,7 +221,7 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS,
std::string Line;
llvm::raw_string_ostream LS(Line);
if (OpPC) {
- if (C.CurrentOp)
+ if (C.getCurrentOp())
LS << " * ";
else
LS << " ";
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 73f2d415cf56e..96f13308d5160 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3721,7 +3721,7 @@ inline bool PushIgnoreDiags(InterpState &S) {
return true;
assert(S.PrevDiags == nullptr);
S.PrevDiags = S.getEvalStatus().Diag;
- S.PrevDiagsEmitted = S.getEvalStatus().DiagEmitted;
+ S.setPrevDiagsEmitted(S.getEvalStatus().DiagEmitted);
S.getEvalStatus().Diag = nullptr;
assert(!S.diagnosing());
return true;
@@ -3732,7 +3732,7 @@ inline bool PopIgnoreDiags(InterpState &S) {
--S.DiagIgnoreDepth;
if (S.DiagIgnoreDepth == 0) {
S.getEvalStatus().Diag = S.PrevDiags;
- S.getEvalStatus().DiagEmitted = S.PrevDiagsEmitted;
+ S.getEvalStatus().DiagEmitted = S.getPrevDiagsEmitted();
S.PrevDiags = nullptr;
}
return true;
diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp
index 44f6fb3216b77..18a865fa14079 100644
--- a/clang/lib/AST/ByteCode/InterpState.cpp
+++ b/clang/lib/AST/ByteCode/InterpState.cpp
@@ -25,7 +25,9 @@ InterpState::InterpState(const EvalSettings &Settings, Program &P,
: State(Ctx.getASTContext(), Settings.EvalStatus), M(M),
FrameAlloc(FrameAlloc), P(P), Stk(Stk), Ctx(Ctx), BottomFrame(*this),
Current(&BottomFrame), StepsLeft(Ctx.getLangOpts().ConstexprStepLimit),
- InfiniteSteps(StepsLeft == 0), EvalID(Ctx.getEvalID()) {
+ EvalID(Ctx.getEvalID()),
+ InitializingPtrs(decltype(this->InitializingPtrs)::withFlags(
+ unsigned(bool(StepsLeft == 0)))) {
InConstantContext = Settings.InConstantContext;
CheckingPotentialConstantExpression =
Settings.CheckingPotentialConstantExpression;
@@ -39,7 +41,9 @@ InterpState::InterpState(const EvalSettings &Settings, Program &P,
: State(Ctx.getASTContext(), Settings.EvalStatus), M(nullptr),
FrameAlloc(FrameAlloc), P(P), Stk(Stk), Ctx(Ctx), BottomFrame(*this),
Current(&BottomFrame), StepsLeft(Ctx.getLangOpts().ConstexprStepLimit),
- InfiniteSteps(StepsLeft == 0), EvalID(Ctx.getEvalID()) {
+ EvalID(Ctx.getEvalID()),
+ InitializingPtrs(decltype(this->InitializingPtrs)::withFlags(
+ unsigned(bool(StepsLeft == 0)))) {
InConstantContext = Settings.InConstantContext;
CheckingPotentialConstantExpression =
Settings.CheckingPotentialConstantExpression;
@@ -52,8 +56,9 @@ InterpState::InterpState(Expr::EvalStatus &Status, Program &P, InterpStack &Stk,
SourceMapper *M)
: State(Ctx.getASTContext(), Status), M(M), FrameAlloc(FrameAlloc), P(P),
Stk(Stk), Ctx(Ctx), BottomFrame(*this), Current(&BottomFrame),
- StepsLeft(Ctx.getLangOpts().ConstexprStepLimit),
- InfiniteSteps(StepsLeft == 0), EvalID(Ctx.getEvalID()) {
+ StepsLeft(Ctx.getLangOpts().ConstexprStepLimit), EvalID(Ctx.getEvalID()),
+ InitializingPtrs(decltype(this->InitializingPtrs)::withFlags(
+ unsigned(bool(StepsLeft == 0)))) {
InConstantContext = true;
CheckingPotentialConstantExpression = false;
CheckingForUndefinedBehavior = true;
diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h
index eb290584285db..4bd6325292afe 100644
--- a/clang/lib/AST/ByteCode/InterpState.h
+++ b/clang/lib/AST/ByteCode/InterpState.h
@@ -21,6 +21,7 @@
#include "InterpFrame.h"
#include "InterpStack.h"
#include "State.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <limits>
namespace clang {
@@ -157,7 +158,7 @@ class InterpState final : public State {
/// Note that a step has been executed. If there are no more steps remaining,
/// diagnoses and returns \c false.
bool noteStep(CodePtr OpPC) {
- if (InfiniteSteps)
+ if (getInfiniteSteps())
return true;
--StepsLeft;
@@ -259,7 +260,7 @@ class InterpState final : public State {
unsigned StepsLeft = 1;
/// Whether infinite evaluation steps have been requested. If this is false,
/// we use the StepsLeft value above.
- const bool InfiniteSteps = false;
+ bool getInfiniteSteps() const { return InitializingPtrs.getFlag(0); }
/// ID identifying this evaluation.
const unsigned EvalID;
@@ -269,7 +270,8 @@ class InterpState final : public State {
/// Things needed to do speculative execution.
SmallVectorImpl<PartialDiagnosticAt> *PrevDiags = nullptr;
- bool PrevDiagsEmitted = false;
+ bool getPrevDiagsEmitted() const { return InitializingPtrs.getFlag(1); }
+ void setPrevDiagsEmitted(bool Value) { InitializingPtrs.setFlag(1, Value); }
#ifndef NDEBUG
unsigned SpeculationDepth = 0;
#endif
@@ -282,7 +284,10 @@ class InterpState final : public State {
/// List of blocks we're currently running either constructors or destructors
/// for.
- llvm::SmallVector<PtrView> InitializingPtrs;
+ llvm::SmallVectorWithFlags<
+ PtrView, llvm::CalculateSmallVectorDefaultInlinedElements<PtrView>::value,
+ 2>
+ InitializingPtrs;
};
class InterpStateCCOverride final {
diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp
index 87f8c870919d1..eaca0156b8dfb 100644
--- a/clang/lib/AST/CommentParser.cpp
+++ b/clang/lib/AST/CommentParser.cpp
@@ -13,6 +13,7 @@
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/DiagnosticComment.h"
#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang {
@@ -33,10 +34,11 @@ class TextTokenRetokenizer {
Parser &P;
/// This flag is set when there are no more tokens we can fetch from lexer.
- bool NoMoreInterestingTokens;
+ bool getNoMoreInterestingTokens() const { return Toks.getFlag(0); }
+ void setNoMoreInterestingTokens(bool Value) { Toks.setFlag(0, Value); }
/// Token buffer: tokens we have processed and lookahead.
- SmallVector<Token, 16> Toks;
+ llvm::SmallVectorWithFlags<Token, 16> Toks;
/// A position in \c Toks.
struct Position {
@@ -119,7 +121,7 @@ class TextTokenRetokenizer {
/// Returns true on success, false if there are no interesting tokens to
/// fetch from lexer.
bool addToken() {
- if (NoMoreInterestingTokens)
+ if (getNoMoreInterestingTokens())
return false;
if (P.Tok.is(tok::newline)) {
@@ -128,12 +130,12 @@ class TextTokenRetokenizer {
P.consumeToken();
if (P.Tok.isNot(tok::text)) {
P.putBack(Newline);
- NoMoreInterestingTokens = true;
+ setNoMoreInterestingTokens(true);
return false;
}
}
if (P.Tok.isNot(tok::text)) {
- NoMoreInterestingTokens = true;
+ setNoMoreInterestingTokens(true);
return false;
}
@@ -169,8 +171,8 @@ class TextTokenRetokenizer {
}
public:
- TextTokenRetokenizer(llvm::BumpPtrAllocator &Allocator, Parser &P):
- Allocator(Allocator), P(P), NoMoreInterestingTokens(false) {
+ TextTokenRetokenizer(llvm::BumpPtrAllocator &Allocator, Parser &P)
+ : Allocator(Allocator), P(P) {
Pos.CurToken = 0;
addToken();
}
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6d390032e2c71..dbfcb0b7357b3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -61,6 +61,7 @@
#include "llvm/ADT/APFixedPoint.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/bit.h"
#include "llvm/Support/CRC.h"
@@ -512,7 +513,7 @@ namespace {
unsigned Index;
/// The stack of integers for tracking version numbers for temporaries.
- SmallVector<unsigned, 2> TempVersionStack = {1};
+ llvm::SmallVectorWithFlags<unsigned, 2> TempVersionStack = {1};
unsigned CurTempVersion = TempVersionStack.back();
unsigned getTempVersion() const { return TempVersionStack.back(); }
@@ -596,7 +597,10 @@ namespace {
/// Whether we're in a context where [[msvc::constexpr]] evaluation is
/// permitted. See MSConstexprDocs for description of permitted contexts.
- bool CanEvalMSConstexpr = false;
+ bool getCanEvalMSConstexpr() const { return TempVersionStack.getFlag(0); }
+ void setCanEvalMSConstexpr(bool Value) {
+ TempVersionStack.setFlag(0, Value);
+ }
private:
APValue &createLocal(APValue::LValueBase Base, const void *Key, QualType T,
@@ -638,11 +642,11 @@ namespace {
CallStackFrame &Frame;
bool OldValue;
explicit MSConstexprContextRAII(CallStackFrame &Frame, bool Value)
- : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
- Frame.CanEvalMSConstexpr = Value;
+ : Frame(Frame), OldValue(Frame.getCanEvalMSConstexpr()) {
+ Frame.setCanEvalMSConstexpr(Value);
}
- ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
+ ~MSConstexprContextRAII() { Frame.setCanEvalMSConstexpr(OldValue); }
};
}
@@ -6591,8 +6595,9 @@ static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc,
// Can we evaluate this function call?
if (Definition && Body &&
- (Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
- Definition->hasAttr<MSConstexprAttr>())))
+ (Definition->isConstexpr() ||
+ (Info.CurrentCall->getCanEvalMSConstexpr() &&
+ Definition->hasAttr<MSConstexprAttr>())))
return true;
const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
@@ -7982,17 +7987,18 @@ class BitCastBuffer {
// FIXME: Its possible under the C++ standard for 'char' to not be 8 bits, but
// we don't support a host or target where that is the case. Still, we should
// use a more generic type in case we ever do.
- SmallVector<std::optional<unsigned char>, 32> Bytes;
+ llvm::SmallVectorWithFlags<std::optional<unsigned char>, 32> Bytes;
static_assert(std::numeric_limits<unsigned char>::digits >= 8,
"Need at least 8 bit unsigned char");
- bool TargetIsLittleEndian;
+ bool getTargetIsLittleEndian() const { return Bytes.getFlag(0); }
+ void setTargetIsLittleEndian(bool Value) { Bytes.setFlag(0, Value); }
public:
BitCastBuffer(CharUnits Width, bool TargetIsLittleEndian)
- : Bytes(Width.getQuantity()),
- TargetIsLittleEndian(TargetIsLittleEndian) {}
+ : Bytes(decltype(this->Bytes)::withFlags(unsigned(TargetIsLittleEndian),
+ Width.getQuantity())) {}
[[nodiscard]] bool readObject(CharUnits Offset, CharUnits Width,
SmallVectorImpl<unsigned char> &Output) const {
@@ -8003,13 +8009,13 @@ class BitCastBuffer {
return false;
Output.push_back(*Bytes[I.getQuantity()]);
}
- if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
+ if (llvm::sys::IsLittleEndianHost != getTargetIsLittleEndian())
std::reverse(Output.begin(), Output.end());
return true;
}
void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
- if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
+ if (llvm::sys::IsLittleEndianHost != getTargetIsLittleEndian())
std::reverse(Input.begin(), Input.end());
size_t Index = 0;
@@ -11113,7 +11119,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
if (OperatorNew->isReservedGlobalPlacementOperator()) {
if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
- (Info.CurrentCall->CanEvalMSConstexpr &&
+ (Info.CurrentCall->getCanEvalMSConstexpr() &&
OperatorNew->hasAttr<MSConstexprAttr>())) {
if (!EvaluatePointer(E->getPlacementArg(0), Result, Info))
return false;
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 74edee531e48a..59ffd4f9a23bf 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -31,6 +31,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/MD5.h"
@@ -316,7 +317,7 @@ class MicrosoftCXXNameMangler {
unsigned StructorType;
typedef llvm::SmallVector<std::string, 10> BackRefVec;
- BackRefVec NameBackReferences;
+ llvm::SmallVectorWithFlagsFor<BackRefVec, 1> NameBackReferences;
typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
ArgBackRefMap FunArgBackReferences;
@@ -332,7 +333,7 @@ class MicrosoftCXXNameMangler {
ASTContext &getASTContext() const { return Context.getASTContext(); }
- const bool PointersAre64Bit;
+ bool getPointersAre64Bit() const { return NameBackReferences.getFlag(0); }
DiagnosticBuilder Error(SourceLocation, StringRef, StringRef);
DiagnosticBuilder Error(SourceLocation, StringRef);
@@ -344,23 +345,26 @@ class MicrosoftCXXNameMangler {
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
: Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
- TemplateArgStringStorage(TemplateArgStringStorageAlloc),
- PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
- LangAS::Default) == 64) {}
+ NameBackReferences(decltype(this->NameBackReferences)::withFlags(
+ unsigned(bool(C.getASTContext().getTargetInfo().getPointerWidth(
+ LangAS::Default) == 64)))),
+ TemplateArgStringStorage(TemplateArgStringStorageAlloc) {}
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
const CXXConstructorDecl *D, CXXCtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
- TemplateArgStringStorage(TemplateArgStringStorageAlloc),
- PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
- LangAS::Default) == 64) {}
+ NameBackReferences(decltype(this->NameBackReferences)::withFlags(
+ unsigned(bool(C.getASTContext().getTargetInfo().getPointerWidth(
+ LangAS::Default) == 64)))),
+ TemplateArgStringStorage(TemplateArgStringStorageAlloc) {}
MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
const CXXDestructorDecl *D, CXXDtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
- TemplateArgStringStorage(TemplateArgStringStorageAlloc),
- PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(
- LangAS::Default) == 64) {}
+ NameBackReferences(decltype(this->NameBackReferences)::withFlags(
+ unsigned(bool(C.getASTContext().getTargetInfo().getPointerWidth(
+ LangAS::Default) == 64)))),
+ TemplateArgStringStorage(TemplateArgStringStorageAlloc) {}
raw_ostream &getStream() const { return Out; }
@@ -415,8 +419,8 @@ class MicrosoftCXXNameMangler {
bool is64BitPointer(Qualifiers Quals) const {
LangAS AddrSpace = Quals.getAddressSpace();
return AddrSpace == LangAS::ptr64 ||
- (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||
- AddrSpace == LangAS::ptr32_uptr));
+ (getPointersAre64Bit() && !(AddrSpace == LangAS::ptr32_sptr ||
+ AddrSpace == LangAS::ptr32_uptr));
}
void mangleUnqualifiedName(GlobalDecl GD) {
@@ -1443,7 +1447,7 @@ void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
// struct __block_literal *
Out << 'P';
// __ptr64
- if (PointersAre64Bit)
+ if (getPointersAre64Bit())
Out << 'E';
Out << 'A';
mangleArtificialTagType(TagTypeKind::Struct,
@@ -1658,7 +1662,8 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
// Templates have their own context for back references.
ArgBackRefMap OuterFunArgsContext;
ArgBackRefMap OuterTemplateArgsContext;
- BackRefVec OuterTemplateContext;
+ auto OuterTemplateContext =
+ decltype(NameBackReferences)::withFlags(NameBackReferences.getFlags());
PassObjectSizeArgsSet OuterPassObjectSizeArgs;
NameBackReferences.swap(OuterTemplateContext);
FunArgBackReferences.swap(OuterFunArgsContext);
@@ -2338,8 +2343,9 @@ MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
QualType PointeeType) {
// Check if this is a default 64-bit pointer or has __ptr64 qualifier.
- bool is64Bit = PointeeType.isNull() ? PointersAre64Bit :
- is64BitPointer(PointeeType.getQualifiers());
+ bool is64Bit = PointeeType.isNull()
+ ? getPointersAre64Bit()
+ : is64BitPointer(PointeeType.getQualifiers());
if (is64Bit && (PointeeType.isNull() || !PointeeType->isFunctionType()))
Out << 'E';
@@ -3156,7 +3162,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// extra argument is not reflected in the AST.
if (StructorType == Dtor_Deleting ||
StructorType == Dtor_VectorDeleting) {
- Out << (PointersAre64Bit ? "PEAXI at Z" : "PAXI at Z");
+ Out << (getPointersAre64Bit() ? "PEAXI at Z" : "PAXI at Z");
return;
}
// The vbase destructor returns void which is not reflected in the AST.
@@ -3837,7 +3843,8 @@ void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
ArgBackRefMap OuterFunArgsContext;
ArgBackRefMap OuterTemplateArgsContext;
- BackRefVec OuterTemplateContext;
+ auto OuterTemplateContext =
+ decltype(NameBackReferences)::withFlags(NameBackReferences.getFlags());
FunArgBackReferences.swap(OuterFunArgsContext);
TemplateArgBackReferences.swap(OuterTemplateArgsContext);
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 5e338c960878b..5308bc51efd83 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -1732,11 +1732,11 @@ OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar,
// Trailing layout: Expr*[1 + NumPrefs + NumAttrs], unsigned[NumPrefs].
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, unsigned>(1 + NumPrefs + NumAttrs, NumPrefs));
- auto *Clause = new (Mem)
- OMPInitClause(InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc,
- LParenLoc, VarLoc, EndLoc, /*VarListN=*/1 + NumPrefs);
+ auto *Clause = new (Mem) OMPInitClause(
+ InteropInfo.isTarget(), InteropInfo.isTargetSync(), StartLoc, LParenLoc,
+ VarLoc, EndLoc, /*VarListN=*/1 + NumPrefs);
Clause->NumAttrs = NumAttrs;
- Clause->HasPreferAttrs = InteropInfo.HasPreferAttrs;
+ Clause->HasPreferAttrs = InteropInfo.hasPreferAttrs();
Expr **E = Clause->getTrailingObjects<Expr *>();
E[0] = InteropVar;
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 40b747da5f9bc..336ea9fde14ca 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/RecordLayout.h"
#include "clang/AST/VTableBuilder.h"
#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
@@ -40,10 +41,11 @@ struct BaseSubobjectInfo {
const CXXRecordDecl *Class;
/// IsVirtual - Whether the BaseInfo represents a virtual base or not.
- bool IsVirtual;
+ bool getIsVirtual() const { return Bases.getFlag(0); }
+ void setIsVirtual(bool Value) { Bases.setFlag(0, Value); }
/// Bases - Information about the base subobjects.
- SmallVector<BaseSubobjectInfo*, 4> Bases;
+ llvm::SmallVectorWithFlags<BaseSubobjectInfo *, 4> Bases;
/// PrimaryVirtualBaseInfo - Holds the base info for the primary virtual base
/// of this base info (if one exists).
@@ -278,7 +280,7 @@ EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
// Traverse all non-virtual bases.
const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
for (const BaseSubobjectInfo *Base : Info->Bases) {
- if (Base->IsVirtual)
+ if (Base->getIsVirtual())
continue;
CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
@@ -326,7 +328,7 @@ void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
// Traverse all non-virtual bases.
const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
for (const BaseSubobjectInfo *Base : Info->Bases) {
- if (Base->IsVirtual)
+ if (Base->getIsVirtual())
continue;
CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
@@ -583,7 +585,7 @@ class ItaniumRecordLayoutBuilder {
/// \brief The maximum of the alignments of top-level members.
CharUnits UnadjustedAlignment;
- SmallVector<uint64_t, 16> FieldOffsets;
+ llvm::SmallVectorWithFlags<uint64_t, 16, 4> FieldOffsets;
/// Whether the external AST source has provided a layout for this
/// record.
@@ -642,20 +644,28 @@ class ItaniumRecordLayoutBuilder {
/// PrimaryBaseIsVirtual - Whether the primary base of the class we're laying
/// out is virtual.
- bool PrimaryBaseIsVirtual;
+ bool getPrimaryBaseIsVirtual() const { return FieldOffsets.getFlag(0); }
+ void setPrimaryBaseIsVirtual(bool Value) { FieldOffsets.setFlag(0, Value); }
/// HasOwnVFPtr - Whether the class provides its own vtable/vftbl
/// pointer, as opposed to inheriting one from a primary base class.
- bool HasOwnVFPtr;
+ bool getHasOwnVFPtr() const { return FieldOffsets.getFlag(1); }
+ void setHasOwnVFPtr(bool Value) { FieldOffsets.setFlag(1, Value); }
/// the flag of field offset changing due to packed attribute.
- bool HasPackedField;
+ bool getHasPackedField() const { return FieldOffsets.getFlag(2); }
+ void setHasPackedField(bool Value) { FieldOffsets.setFlag(2, Value); }
/// HandledFirstNonOverlappingEmptyField - An auxiliary field used for AIX.
/// When there are OverlappingEmptyFields existing in the aggregate, the
/// flag shows if the following first non-empty or empty-but-non-overlapping
/// field has been handled, if any.
- bool HandledFirstNonOverlappingEmptyField;
+ bool getHandledFirstNonOverlappingEmptyField() const {
+ return FieldOffsets.getFlag(3);
+ }
+ void setHandledFirstNonOverlappingEmptyField(bool Value) {
+ FieldOffsets.setFlag(3, Value);
+ }
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
@@ -695,8 +705,6 @@ class ItaniumRecordLayoutBuilder {
NonVirtualAlignment(CharUnits::One()),
PreferredNVAlignment(CharUnits::One()),
PaddedFieldSize(CharUnits::Zero()), PrimaryBase(nullptr),
- PrimaryBaseIsVirtual(false), HasOwnVFPtr(false), HasPackedField(false),
- HandledFirstNonOverlappingEmptyField(false),
FirstNearlyEmptyVBase(nullptr) {}
void Layout(const RecordDecl *D);
@@ -833,7 +841,7 @@ void ItaniumRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
// base.
if (!IndirectPrimaryBases.count(Base)) {
PrimaryBase = Base;
- PrimaryBaseIsVirtual = true;
+ setPrimaryBaseIsVirtual(true);
return;
}
@@ -871,7 +879,7 @@ void ItaniumRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
if (Base->isDynamicClass()) {
// We found it.
PrimaryBase = Base;
- PrimaryBaseIsVirtual = false;
+ setPrimaryBaseIsVirtual(false);
return;
}
}
@@ -889,7 +897,7 @@ void ItaniumRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
// Otherwise, it is the first indirect primary base class, if one exists.
if (FirstNearlyEmptyVBase) {
PrimaryBase = FirstNearlyEmptyVBase;
- PrimaryBaseIsVirtual = true;
+ setPrimaryBaseIsVirtual(true);
return;
}
@@ -916,7 +924,7 @@ BaseSubobjectInfo *ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
}
Info->Class = RD;
- Info->IsVirtual = IsVirtual;
+ Info->setIsVirtual(IsVirtual);
Info->Derived = nullptr;
Info->PrimaryVirtualBaseInfo = nullptr;
@@ -1024,7 +1032,7 @@ void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases(
// If we have a primary base class, lay it out.
if (PrimaryBase) {
- if (PrimaryBaseIsVirtual) {
+ if (getPrimaryBaseIsVirtual()) {
// If the primary virtual base was a primary virtual base of some other
// base class we'll have to steal it.
BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase);
@@ -1056,10 +1064,10 @@ void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases(
CharUnits PtrAlign = Context.toCharUnitsFromBits(
Context.getTargetInfo().getPointerAlign(LangAS::Default));
EnsureVTablePointerAlignment(PtrAlign);
- HasOwnVFPtr = true;
+ setHasOwnVFPtr(true);
assert(!IsUnion && "Unions cannot be dynamic classes.");
- HandledFirstNonOverlappingEmptyField = true;
+ setHandledFirstNonOverlappingEmptyField(true);
setSize(getSize() + PtrWidth);
setDataSize(getSize());
@@ -1077,7 +1085,7 @@ void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases(
// Skip the primary base, because we've already laid it out. The
// !PrimaryBaseIsVirtual check is required because we might have a
// non-virtual base of the same type as a primary virtual base.
- if (BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual)
+ if (BaseDecl == PrimaryBase && !getPrimaryBaseIsVirtual())
continue;
// Lay out the base.
@@ -1108,7 +1116,7 @@ void ItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(
// First, check if we have a virtual primary base to add offsets for.
if (Info->PrimaryVirtualBaseInfo) {
- assert(Info->PrimaryVirtualBaseInfo->IsVirtual &&
+ assert(Info->PrimaryVirtualBaseInfo->getIsVirtual() &&
"Primary virtual base is not virtual!");
if (Info->PrimaryVirtualBaseInfo->Derived == Info) {
// Add the offset.
@@ -1125,7 +1133,7 @@ void ItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(
// Now go through all direct non-virtual bases.
const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
for (const BaseSubobjectInfo *Base : Info->Bases) {
- if (Base->IsVirtual)
+ if (Base->getIsVirtual())
continue;
CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class);
@@ -1140,7 +1148,7 @@ void ItaniumRecordLayoutBuilder::LayoutVirtualBases(
if (MostDerivedClass == RD) {
PrimaryBase = this->PrimaryBase;
- PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual;
+ PrimaryBaseIsVirtual = this->getPrimaryBaseIsVirtual();
} else {
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
PrimaryBase = Layout.getPrimaryBase();
@@ -1204,7 +1212,7 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
// Query the external layout to see if it provides an offset.
bool HasExternalLayout = false;
if (UseExternalLayout) {
- if (Base->IsVirtual)
+ if (Base->getIsVirtual())
HasExternalLayout = External.getExternalVBaseOffset(Base->Class, Offset);
else
HasExternalLayout = External.getExternalNVBaseOffset(Base->Class, Offset);
@@ -1235,10 +1243,10 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
// non-union classes if the source of the alignment (the current base in
// this context) follows introduction of the first subobject with
// exclusively allocated space or zero-extent array.
- if (!Base->Class->isEmpty() && !HandledFirstNonOverlappingEmptyField) {
+ if (!Base->Class->isEmpty() && !getHandledFirstNonOverlappingEmptyField()) {
// By handling a base class that is not empty, we're handling the
// "first (inherited) member".
- HandledFirstNonOverlappingEmptyField = true;
+ setHandledFirstNonOverlappingEmptyField(true);
} else if (!IsNaturalAlign) {
UnpackedPreferredBaseAlign = UnpackedBaseAlign;
PreferredBaseAlign = BaseAlign;
@@ -1341,8 +1349,8 @@ void ItaniumRecordLayoutBuilder::InitializeLayout(const Decl *D) {
UpdateAlignment(Context.toCharUnitsFromBits(MaxAlign));
}
- HandledFirstNonOverlappingEmptyField =
- !Context.getTargetInfo().defaultsToAIXPowerAlignment() || IsNaturalAlign;
+ setHandledFirstNonOverlappingEmptyField(
+ !Context.getTargetInfo().defaultsToAIXPowerAlignment() || IsNaturalAlign);
// If there is an external AST source, ask it for the various offsets.
if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
@@ -1859,7 +1867,8 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
const bool DefaultsToAIXPowerAlignment =
Context.getTargetInfo().defaultsToAIXPowerAlignment();
bool FoundFirstNonOverlappingEmptyFieldForAIX = false;
- if (DefaultsToAIXPowerAlignment && !HandledFirstNonOverlappingEmptyField) {
+ if (DefaultsToAIXPowerAlignment &&
+ !getHandledFirstNonOverlappingEmptyField()) {
assert(FieldOffset == CharUnits::Zero() &&
"The first non-overlapping empty field should have been handled.");
@@ -1871,7 +1880,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
// invocation of this function; record it as handled for future
// invocations (except for unions, because the current field does not
// represent all "firsts").
- HandledFirstNonOverlappingEmptyField = !IsUnion;
+ setHandledFirstNonOverlappingEmptyField(!IsUnion);
}
}
@@ -2202,7 +2211,7 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
// attribute on such a type does allow the type to be packed into other
// structures that use the packed attribute.
if (Packed && UnpackedAlignment <= Alignment &&
- UnpackedSizeInBits == getSizeInBits() && !HasPackedField &&
+ UnpackedSizeInBits == getSizeInBits() && !getHasPackedField() &&
(!CXXRD || CXXRD->isPOD() ||
Context.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver15)))
Diag(D->getLocation(), diag::warn_unnecessary_packed)
@@ -2320,7 +2329,7 @@ void ItaniumRecordLayoutBuilder::CheckFieldPadding(
unsigned UnpackedAlign, bool isPacked, const FieldDecl *D) {
::CheckFieldPadding(Context, IsUnion, Offset, UnpaddedOffset, D);
if (isPacked && Offset != UnpackedOffset) {
- HasPackedField = true;
+ setHasPackedField(true);
}
}
@@ -3518,13 +3527,13 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
Builder.PreferredAlignment, Builder.UnadjustedAlignment,
/*RequiredAlignment : used by MS-ABI)*/
Builder.Alignment, /*PragmaPackResistantAlignment=*/CharUnits::Zero(),
- Builder.HasOwnVFPtr, RD->isDynamicClass(),
+ Builder.getHasOwnVFPtr(), RD->isDynamicClass(),
CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets,
NonVirtualSize, Builder.NonVirtualAlignment,
Builder.PreferredNVAlignment, Builder.NonVirtualAlignment,
EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase,
- Builder.PrimaryBaseIsVirtual, nullptr, false, false, Builder.Bases,
- Builder.VBases);
+ Builder.getPrimaryBaseIsVirtual(), nullptr, false, false,
+ Builder.Bases, Builder.VBases);
} else {
ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
Builder.Layout(D);
diff --git a/clang/lib/AST/VTTBuilder.cpp b/clang/lib/AST/VTTBuilder.cpp
index 89b58b557ddca..1fcfe165f29f4 100644
--- a/clang/lib/AST/VTTBuilder.cpp
+++ b/clang/lib/AST/VTTBuilder.cpp
@@ -27,12 +27,12 @@ using namespace clang;
#define DUMP_OVERRIDERS 0
-VTTBuilder::VTTBuilder(ASTContext &Ctx,
- const CXXRecordDecl *MostDerivedClass,
+VTTBuilder::VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
bool GenerateDefinition)
: Ctx(Ctx), MostDerivedClass(MostDerivedClass),
- MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)),
- GenerateDefinition(GenerateDefinition) {
+ VTTComponents(decltype(this->VTTComponents)::withFlags(
+ unsigned(GenerateDefinition))),
+ MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)) {
// Lay out this VTT.
LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()),
/*BaseIsVirtual=*/false);
@@ -47,7 +47,7 @@ void VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
}
- if (!GenerateDefinition) {
+ if (!getGenerateDefinition()) {
VTTComponents.push_back(VTTComponent());
return;
}
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index 3c05d4b22b03e..909cafc36b572 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -806,7 +807,10 @@ class ItaniumVTableBuilder {
/// MostDerivedClassIsVirtual - Whether the most derived class is a virtual
/// base. (This only makes sense when building a construction vtable).
- bool MostDerivedClassIsVirtual;
+ bool getMostDerivedClassIsVirtual() const { return Components.getFlag(0); }
+ void setMostDerivedClassIsVirtual(bool Value) {
+ Components.setFlag(0, Value);
+ }
/// LayoutClass - The class we're using for layout information. Will be
/// different than the most derived class if we're building a construction
@@ -828,7 +832,7 @@ class ItaniumVTableBuilder {
VBaseOffsetOffsetsMapTy VBaseOffsetOffsets;
/// Components - The components of the vtable being built.
- SmallVector<VTableComponent, 64> Components;
+ llvm::SmallVectorWithFlags<VTableComponent, 64> Components;
/// AddressPoints - Address points for the vtable being built.
AddressPointsMapTy AddressPoints;
@@ -1004,9 +1008,10 @@ class ItaniumVTableBuilder {
const CXXRecordDecl *LayoutClass)
: VTables(VTables), MostDerivedClass(MostDerivedClass),
MostDerivedClassOffset(MostDerivedClassOffset),
- MostDerivedClassIsVirtual(MostDerivedClassIsVirtual),
LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()),
- Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) {
+ Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass),
+ Components(decltype(this->Components)::withFlags(
+ unsigned(MostDerivedClassIsVirtual))) {
assert(!Context.getTargetInfo().getCXXABI().isMicrosoft());
LayoutVTable();
@@ -1661,11 +1666,10 @@ void ItaniumVTableBuilder::AddMethods(
}
void ItaniumVTableBuilder::LayoutVTable() {
- LayoutPrimaryAndSecondaryVTables(BaseSubobject(MostDerivedClass,
- CharUnits::Zero()),
- /*BaseIsMorallyVirtual=*/false,
- MostDerivedClassIsVirtual,
- MostDerivedClassOffset);
+ LayoutPrimaryAndSecondaryVTables(
+ BaseSubobject(MostDerivedClass, CharUnits::Zero()),
+ /*BaseIsMorallyVirtual=*/false, getMostDerivedClassIsVirtual(),
+ MostDerivedClassOffset);
VisitedVirtualBasesSetTy VBases;
@@ -2534,12 +2538,13 @@ class VFTableBuilder {
const FinalOverriders Overriders;
/// Components - The components of the vftable being built.
- SmallVector<VTableComponent, 64> Components;
+ llvm::SmallVectorWithFlags<VTableComponent, 64> Components;
MethodVFTableLocationsTy MethodVFTableLocations;
/// Does this class have an RTTI component?
- bool HasRTTIComponent = false;
+ bool getHasRTTIComponent() const { return Components.getFlag(0); }
+ void setHasRTTIComponent(bool Value) { Components.setFlag(0, Value); }
/// MethodInfo - Contains information about a method in a vtable.
/// (Used for computing 'this' pointer adjustment thunks.
@@ -2631,7 +2636,7 @@ class VFTableBuilder {
void LayoutVFTable() {
// RTTI data goes before all other entries.
- if (HasRTTIComponent)
+ if (getHasRTTIComponent())
Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
BasesSetVectorTy VisitedBases;
@@ -2681,7 +2686,7 @@ class VFTableBuilder {
// dllimport or extern template instantiations, but eventually we may add a
// flag to support additional devirtualization that needs this.
if (Context.getLangOpts().RTTIData)
- HasRTTIComponent = true;
+ setHasRTTIComponent(true);
LayoutVFTable();
@@ -3162,7 +3167,8 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
// If we got here, MD is a method not seen in any of the sub-bases or
// it requires return adjustment. Insert the method info for this method.
MethodInfo MI(VBIndex,
- HasRTTIComponent ? Components.size() - 1 : Components.size(),
+ getHasRTTIComponent() ? Components.size() - 1
+ : Components.size(),
ReturnAdjustingThunk);
assert(!MethodInfoMap.count(MD) &&
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 556e08f5c1df8..931cdd1d7470d 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -45,6 +45,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DOTGraphTraits.h"
@@ -700,7 +701,8 @@ class CFGBuilder {
struct TempDtorContext {
TempDtorContext() = default;
TempDtorContext(TryResult KnownExecuted)
- : IsConditional(true), KnownExecuted(KnownExecuted) {}
+ : CollectedMTEs(decltype(this->CollectedMTEs)::withFlags(1)),
+ KnownExecuted(KnownExecuted) {}
/// Returns whether we need to start a new branch for a temporary destructor
/// call. This is the case when the temporary destructor is
/// conditionally executed, and it is the first one we encounter while
@@ -708,7 +710,7 @@ class CFGBuilder {
/// will be added to the same block and are executed under the same
/// condition.
bool needsTempDtorBranch() const {
- return IsConditional && !TerminatorExpr;
+ return getIsConditional() && !TerminatorExpr;
}
/// Remember the successor S of a temporary destructor decision branch for
@@ -722,11 +724,18 @@ class CFGBuilder {
CollectedMTEs.push_back(MTE);
}
- const bool IsConditional = false;
- SmallVector<const MaterializeTemporaryExpr *, 5> CollectedMTEs;
+ bool getIsConditional() const { return CollectedMTEs.getFlag(0); }
+ llvm::SmallVectorWithFlags<const MaterializeTemporaryExpr *, 5>
+ CollectedMTEs;
const TryResult KnownExecuted = true;
CFGBlock *Succ = nullptr;
CXXBindTemporaryExpr *TerminatorExpr = nullptr;
+
+ public:
+ TempDtorContext(const TempDtorContext &) = default;
+ TempDtorContext(TempDtorContext &&) = default;
+ TempDtorContext &operator=(const TempDtorContext &) = delete;
+ TempDtorContext &operator=(TempDtorContext &&) = delete;
};
// Visitors to walk an AST and generate destructors of temporaries in
@@ -5298,7 +5307,8 @@ CFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaries(
InsertTempDecisionBlock(RHSContext);
if (BuildOpts.AddLifetime)
- Context.CollectedMTEs.append(RHSContext.CollectedMTEs);
+ Context.CollectedMTEs.append(RHSContext.CollectedMTEs.begin(),
+ RHSContext.CollectedMTEs.end());
return Block;
}
@@ -5409,8 +5419,10 @@ CFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaries(
InsertTempDecisionBlock(FalseContext);
}
if (BuildOpts.AddLifetime) {
- Context.CollectedMTEs.append(TrueContext.CollectedMTEs);
- Context.CollectedMTEs.append(FalseContext.CollectedMTEs);
+ Context.CollectedMTEs.append(TrueContext.CollectedMTEs.begin(),
+ TrueContext.CollectedMTEs.end());
+ Context.CollectedMTEs.append(FalseContext.CollectedMTEs.begin(),
+ FalseContext.CollectedMTEs.end());
}
return Block;
diff --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp
index 95f3fdbe6e999..6242882c8d487 100644
--- a/clang/lib/Analysis/CalledOnceCheck.cpp
+++ b/clang/lib/Analysis/CalledOnceCheck.cpp
@@ -31,6 +31,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -609,9 +610,9 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
private:
CalledOnceChecker(AnalysisDeclContext &AC, CalledOnceCheckHandler &Handler,
bool CheckConventionalParameters)
- : FunctionCFG(*AC.getCFG()), AC(AC), Handler(Handler),
- CheckConventionalParameters(CheckConventionalParameters),
- CurrentState(0) {
+ : FunctionCFG(*AC.getCFG()), AC(AC), Handler(Handler), CurrentState(0),
+ TrackedParams(decltype(TrackedParams)::withFlags(
+ unsigned(CheckConventionalParameters))) {
initDataStructures();
assert((size() == 0 || !States.empty()) &&
"Data structures are inconsistent");
@@ -815,7 +816,7 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
// ... or if we've seen variables with cleanup functions.
// We can't reason that we've seen every path in this case,
// and thus abandon reporting any warnings that imply that.
- !FunctionHasCleanupVars)
+ !getFunctionHasCleanupVars())
return;
// We are looking for a pair of blocks A, B so that the following is true:
@@ -1034,7 +1035,7 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
bool shouldBeCalledOnce(const ParmVarDecl *Parameter) const {
return isExplicitlyMarked(Parameter) ||
- (CheckConventionalParameters &&
+ (getCheckConventionalParameters() &&
(isConventional(Parameter->getName()) ||
hasConventionalSuffix(Parameter->getName())) &&
isConventional(Parameter->getType()));
@@ -1068,7 +1069,7 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
}
return shouldBeCalledOnce(Function->getParamDecl(ParamIndex)) ||
- (CheckConventionalParameters &&
+ (getCheckConventionalParameters() &&
isOnlyParameterConventional(Function));
}
@@ -1086,7 +1087,7 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
const ParmVarDecl *Parameter = Method->getParamDecl(ParamIndex);
return shouldBeCalledOnce(Parameter) ||
- (CheckConventionalParameters &&
+ (getCheckConventionalParameters() &&
isConventionalSelectorPiece(MethodSelector, ParamIndex,
Parameter->getType()));
}
@@ -1343,7 +1344,7 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
void handleConditional(const CFGBlock *BB, const Expr *Condition,
State &ToAlter) const {
handleParameterCheck(BB, Condition, ToAlter);
- if (SuppressOnConventionalErrorPaths) {
+ if (getSuppressOnConventionalErrorPaths()) {
handleConventionalCheck(BB, Condition, ToAlter);
}
}
@@ -1611,7 +1612,7 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
}
if (Var->hasAttr<CleanupAttr>()) {
- FunctionHasCleanupVars = true;
+ setFunctionHasCleanupVars(true);
}
}
}
@@ -1672,24 +1673,38 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
const CFG &FunctionCFG;
AnalysisDeclContext &AC;
CalledOnceCheckHandler &Handler;
- bool CheckConventionalParameters;
+ bool getCheckConventionalParameters() const {
+ return TrackedParams.getFlag(0);
+ }
+ void setCheckConventionalParameters(bool Value) {
+ TrackedParams.setFlag(0, Value);
+ }
// As of now, we turn this behavior off. So, we still are going to report
// missing calls on paths that look like it was intentional.
// Technically such reports are true positives, but they can make some users
// grumpy because of the sheer number of warnings.
// It can be turned back on if we decide that we want to have the other way
// around.
- bool SuppressOnConventionalErrorPaths = false;
+ bool getSuppressOnConventionalErrorPaths() const {
+ return TrackedParams.getFlag(1);
+ }
+ void setSuppressOnConventionalErrorPaths(bool Value) {
+ TrackedParams.setFlag(1, Value);
+ }
// The user can annotate variable declarations with cleanup functions, which
// essentially imposes a custom destructor logic on that variable.
// It is possible to use it, however, to call tracked parameters on all exits
// from the function. For this reason, we track the fact that the function
// actually has these.
- bool FunctionHasCleanupVars = false;
+ bool getFunctionHasCleanupVars() const { return TrackedParams.getFlag(2); }
+ void setFunctionHasCleanupVars(bool Value) {
+ TrackedParams.setFlag(2, Value);
+ }
State CurrentState;
- ParamSizedVector<const ParmVarDecl *> TrackedParams;
+ llvm::SmallVectorWithFlagsFor<ParamSizedVector<const ParmVarDecl *>, 3>
+ TrackedParams;
CFGSizedVector<State> States;
};
diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 6a805bb7be2d8..b56cf863cf2c4 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -364,7 +364,7 @@ void FactsGenerator::VisitUnaryOperator(const UnaryOperator *UO) {
return;
// Skip address-of on void expressions: GNU C permits them, but void itself
// has no origins to track.
- if (IsCMode && SubExpr->getType()->isVoidType())
+ if (getIsCMode() && SubExpr->getType()->isVoidType())
return;
assert(!SubExpr->getType()->isVoidType() &&
"Taking address of void is not valid in C++");
@@ -456,7 +456,7 @@ void FactsGenerator::handleAssignment(const Expr *TargetExpr,
// In C, assignment expressions are not GLValues, so the assignment result has
// the assigned value origins, not the LHS storage origin.
- if (IsCMode)
+ if (getIsCMode())
LHSList = LHSList->peelOuterOrigin();
flow(getOriginsList(*TargetExpr), LHSList, /*Kill=*/true);
}
@@ -503,7 +503,8 @@ void FactsGenerator::VisitBinaryOperator(const BinaryOperator *BO) {
// (storage) origin.
if (BO->getType()->isPointerType()) {
OriginList *LHSList = getOriginsList(*BO->getLHS());
- flow(getOriginsList(*BO), IsCMode ? LHSList->peelOuterOrigin() : LHSList,
+ flow(getOriginsList(*BO),
+ getIsCMode() ? LHSList->peelOuterOrigin() : LHSList,
/*Kill=*/true);
}
return;
@@ -683,7 +684,7 @@ void FactsGenerator::VisitLambdaExpr(const LambdaExpr *LE) {
void FactsGenerator::VisitArraySubscriptExpr(const ArraySubscriptExpr *ASE) {
// Some C subscripts do not refer to addressable storage with origins, such as
// GNU void-pointer subscripts and vector element extraction from rvalues.
- if (IsCMode && !ASE->isGLValue())
+ if (getIsCMode() && !ASE->isGLValue())
return;
assert(ASE->isGLValue() && "Array subscript should be a GL value");
OriginList *Dst = getOriginsList(*ASE);
diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp
index 80a21cba8e2fc..d832adeb58e3a 100644
--- a/clang/lib/Basic/Module.cpp
+++ b/clang/lib/Basic/Module.cpp
@@ -38,21 +38,20 @@ Module::Module(ModuleConstructorTag, StringRef Name,
SourceLocation DefinitionLoc, Module *Parent, bool IsFramework,
bool IsExplicit, unsigned VisibilityID)
: Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
- VisibilityID(VisibilityID), IsUnimportable(false),
- HasIncompatibleModuleFile(false), IsAvailable(true),
- IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
- IsSystem(false), IsExternC(false), IsInferred(false),
- InferSubmodules(false), InferExplicitSubmodules(false),
- InferExportWildcard(false), ConfigMacrosExhaustive(false),
- NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
- NamedModuleHasInit(true), NameVisibility(Hidden) {
+ VisibilityID(VisibilityID),
+ HeadersStorage(decltype(this->HeadersStorage)::withFlags(
+ unsigned((unsigned(IsFramework) & 1)) |
+ (unsigned((unsigned(IsExplicit) & 1)) << 1))),
+ Requirements(decltype(this->Requirements)::withFlags(4)),
+ NameVisibility(Hidden),
+ UnresolvedDirectUses(decltype(this->UnresolvedDirectUses)::withFlags(8)) {
if (Parent) {
- IsAvailable = Parent->isAvailable();
- IsUnimportable = Parent->isUnimportable();
- IsSystem = Parent->IsSystem;
- IsExternC = Parent->IsExternC;
- NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
- ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
+ setIsAvailable(Parent->isAvailable());
+ setIsUnimportable(Parent->isUnimportable());
+ setIsSystem(Parent->getIsSystem());
+ setIsExternC(Parent->getIsExternC());
+ setNoUndeclaredIncludes(Parent->getNoUndeclaredIncludes());
+ setModuleMapIsPrivate(Parent->getModuleMapIsPrivate());
Parent->addSubmodule(Name, this);
}
@@ -128,7 +127,7 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
bool Module::isUnimportable(const LangOptions &LangOpts,
const TargetInfo &Target, Requirement &Req,
Module *&ShadowingModule) const {
- if (!IsUnimportable)
+ if (!getIsUnimportable())
return false;
for (const Module *Current = this; Current; Current = Current->Parent) {
@@ -161,7 +160,7 @@ bool Module::isForBuilding(const LangOptions &LangOpts) const {
// When building the implementation of framework Foo, we want to make sure
// that Foo *and* Foo_Private are textually included and no modules are built
// for either.
- if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework &&
+ if (!LangOpts.isCompilingModule() && getTopLevelModule()->getIsFramework() &&
CurrentModule == LangOpts.ModuleName &&
!CurrentModule.ends_with("_Private") &&
TopLevelName.ends_with("_Private"))
@@ -174,7 +173,7 @@ bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
Requirement &Req,
UnresolvedHeaderDirective &MissingHeader,
Module *&ShadowingModule) const {
- if (IsAvailable)
+ if (getIsAvailable())
return true;
if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
@@ -327,7 +326,7 @@ bool Module::directlyUses(const Module *Requested) {
if (!Requested->Parent && Requested->Name == "ptrauth")
return true;
- if (NoUndeclaredIncludes)
+ if (getNoUndeclaredIncludes())
UndeclaredUses.insert(Requested);
return false;
@@ -347,7 +346,7 @@ void Module::addRequirement(StringRef Feature, bool RequiredState,
void Module::markUnavailable(bool Unimportable) {
auto needUpdate = [Unimportable](Module *M) {
- return M->IsAvailable || (!M->IsUnimportable && Unimportable);
+ return M->getIsAvailable() || (!M->getIsUnimportable() && Unimportable);
};
if (!needUpdate(this))
@@ -361,8 +360,9 @@ void Module::markUnavailable(bool Unimportable) {
if (!needUpdate(Current))
continue;
- Current->IsAvailable = false;
- Current->IsUnimportable |= Unimportable;
+ Current->setIsAvailable(false);
+ Current->setIsUnimportable(int(Current->getIsUnimportable()) |
+ (Unimportable));
for (Module *Submodule : Current->submodules()) {
if (needUpdate(Submodule))
Stack.push_back(Submodule);
@@ -402,7 +402,7 @@ Module *Module::getPrivateModuleFragment() const {
void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
// All non-explicit submodules are exported.
for (Module *Mod : submodules())
- if (!Mod->IsExplicit)
+ if (!Mod->getIsExplicit())
Exported.push_back(Mod);
// Find re-exported modules by filtering the list of imported modules.
@@ -477,18 +477,18 @@ void Module::buildVisibleModulesCache() const {
void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
OS.indent(Indent);
- if (IsFramework)
+ if (getIsFramework())
OS << "framework ";
- if (IsExplicit)
+ if (getIsExplicit())
OS << "explicit ";
OS << "module ";
printModuleId(OS, &Name, &Name + 1);
- if (IsSystem || IsExternC) {
+ if (getIsSystem() || getIsExternC()) {
OS.indent(Indent + 2);
- if (IsSystem)
+ if (getIsSystem())
OS << " [system]";
- if (IsExternC)
+ if (getIsExternC())
OS << " [extern_c]";
}
@@ -519,10 +519,10 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
OS << "\"\n";
}
- if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
+ if (!ConfigMacros.empty() || getConfigMacrosExhaustive()) {
OS.indent(Indent + 2);
OS << "config_macros ";
- if (ConfigMacrosExhaustive)
+ if (getConfigMacrosExhaustive())
OS << "[exhaustive]";
for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
if (I)
@@ -579,7 +579,7 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
// them (requires expensive directory iteration + stat calls) when we build
// the module. Regular inferred submodules are OK, as we need to look at all
// those header files anyway.
- if (!Submodule->IsInferred || Submodule->IsFramework)
+ if (!Submodule->getIsInferred() || Submodule->getIsFramework())
Submodule->print(OS, Indent + 2, Dump);
for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
@@ -599,7 +599,7 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
OS.indent(Indent + 2);
OS << "export ";
printModuleId(OS, UnresolvedExports[I].Id);
- if (UnresolvedExports[I].Wildcard)
+ if (UnresolvedExports[I].getWildcard())
OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
OS << "\n";
}
@@ -653,12 +653,12 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
OS << "\"\n";
}
- if (InferSubmodules) {
+ if (getInferSubmodules()) {
OS.indent(Indent + 2);
- if (InferExplicitSubmodules)
+ if (getInferExplicitSubmodules())
OS << "explicit ";
OS << "module * {\n";
- if (InferExportWildcard) {
+ if (getInferExportWildcard()) {
OS.indent(Indent + 4);
OS << "export *\n";
}
diff --git a/clang/lib/Basic/Sarif.cpp b/clang/lib/Basic/Sarif.cpp
index e829b9bb47ad9..091bd16dd9fea 100644
--- a/clang/lib/Basic/Sarif.cpp
+++ b/clang/lib/Basic/Sarif.cpp
@@ -242,8 +242,9 @@ SarifDocumentWriter::createPhysicalLocation(const CharSourceRange &R) {
}
json::Object &SarifDocumentWriter::getCurrentTool() {
- assert(!Closed && "SARIF Document is closed. "
- "Need to call createRun() before using getcurrentTool!");
+ assert(!getClosed() &&
+ "SARIF Document is closed. "
+ "Need to call createRun() before using getcurrentTool!");
// Since Closed = false here, expect there to be at least 1 Run, anything
// else is an invalid state.
@@ -259,7 +260,7 @@ void SarifDocumentWriter::reset() {
void SarifDocumentWriter::endRun() {
// Exit early if trying to close a closed Document.
- if (Closed) {
+ if (getClosed()) {
reset();
return;
}
@@ -320,7 +321,7 @@ void SarifDocumentWriter::endRun() {
reset();
// Mark the document as closed.
- Closed = true;
+ setClosed(true);
}
json::Array
@@ -349,7 +350,7 @@ void SarifDocumentWriter::createRun(StringRef ShortToolName,
endRun();
// Signify a new run has begun.
- Closed = false;
+ setClosed(false);
json::Object Tool{
{"driver",
@@ -367,7 +368,7 @@ void SarifDocumentWriter::createRun(StringRef ShortToolName,
}
json::Object &SarifDocumentWriter::getCurrentRun() {
- assert(!Closed &&
+ assert(!getClosed() &&
"SARIF Document is closed. "
"Can only getCurrentRun() if document is opened via createRun(), "
"create a run first");
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index c9567d263c444..ae284af4e30df 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -320,7 +320,9 @@ LineTableInfo &SourceManager::getLineTable() {
SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr,
bool UserFilesAreVolatile)
- : Diag(Diag), FileMgr(FileMgr), UserFilesAreVolatile(UserFilesAreVolatile) {
+ : Diag(Diag), FileMgr(FileMgr),
+ StoredModuleBuildStack(decltype(this->StoredModuleBuildStack)::withFlags(
+ (unsigned(UserFilesAreVolatile) << 1))) {
clearIDTables();
Diag.setSourceManager(this);
}
@@ -423,15 +425,15 @@ ContentCache &SourceManager::getOrCreateContentCache(FileEntryRef FileEnt,
if (overI == OverriddenFilesInfo->OverriddenFiles.end())
new (Entry) ContentCache(FileEnt);
else
- new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt
- : overI->second,
- overI->second);
+ new (Entry) ContentCache(
+ getOverridenFilesKeepOriginalNameFlag() ? FileEnt : overI->second,
+ overI->second);
} else {
new (Entry) ContentCache(FileEnt);
}
- Entry->IsFileVolatile = UserFilesAreVolatile && !isSystemFile;
- Entry->IsTransient = FilesAreTransient;
+ Entry->IsFileVolatile = getUserFilesAreVolatile() && !isSystemFile;
+ Entry->IsTransient = getFilesAreTransient();
Entry->BufferOverridden |= FileEnt.isNamedPipe();
return *Entry;
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 17d832046363f..e242b1a34e883 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -158,7 +158,7 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
} else {
// Non-constant size type
assert(!cir::MissingFeatures::openMP());
- if (!didCallStackSave) {
+ if (!getDidCallStackSave()) {
// Save the stack.
cir::PointerType defaultTy = allocaInt8PtrTy;
CharUnits align = CharUnits::fromQuantity(
@@ -169,7 +169,7 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
assert(v.getType() == allocaInt8PtrTy);
builder.createStore(loc, v, stack);
- didCallStackSave = true;
+ setDidCallStackSave(true);
// Push a cleanup block and restore the stack there.
// FIXME: in general circumstances, this should be an EH cleanup.
@@ -1532,7 +1532,7 @@ void CIRGenFunction::maybeEmitDeferredVarDeclInit(const VarDecl *vd) {
}
bool CIRGenFunction::emitLifetimeStartOp(mlir::Location loc, mlir::Value addr) {
- if (!shouldEmitLifetimeMarkers)
+ if (!getShouldEmitLifetimeMarkers())
return false;
assert(mlir::cast<cir::PointerType>(addr.getType()).getAddrSpace() ==
@@ -1544,7 +1544,7 @@ bool CIRGenFunction::emitLifetimeStartOp(mlir::Location loc, mlir::Value addr) {
}
void CIRGenFunction::emitLifetimeEndOp(mlir::Location loc, mlir::Value addr) {
- if (!shouldEmitLifetimeMarkers)
+ if (!getShouldEmitLifetimeMarkers())
return;
assert(mlir::cast<cir::PointerType>(addr.getType()).getAddrSpace() ==
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 14fc9cdff3ab6..d3cbdbbbfa777 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -49,8 +49,8 @@ CIRGenFunction::CIRGenFunction(CIRGenModule &cgm, CIRGenBuilderTy &builder,
: CIRGenTypeCache(cgm), cgm{cgm}, builder(builder),
curFPFeatures(cgm.getLangOpts()) {
ehStack.setCGF(this);
- shouldEmitLifetimeMarkers = CodeGenUtils::shouldEmitLifetimeMarkers(
- cgm.getCodeGenOpts(), getContext().getLangOpts());
+ setShouldEmitLifetimeMarkers(CodeGenUtils::shouldEmitLifetimeMarkers(
+ cgm.getCodeGenOpts(), getContext().getLangOpts()));
}
CIRGenFunction::~CIRGenFunction() {}
@@ -402,7 +402,7 @@ void CIRGenFunction::LexicalScope::emitImplicitReturn() {
// That influences whether the terminating op is trap, unreachable, or
// return.
if (fd && cgf.getLangOpts().CPlusPlus && !fd->hasImplicitReturnZero() &&
- !cgf.sawAsmBlock && !fd->getReturnType()->isVoidType() &&
+ !cgf.getSawAsmBlock() && !fd->getReturnType()->isVoidType() &&
builder.getInsertionBlock() &&
!previousOpIsNonYieldingCleanup(builder.getInsertionBlock())) {
bool shouldEmitUnreachable =
@@ -521,7 +521,7 @@ void CIRGenFunction::startFunction(GlobalDecl gd, QualType returnType,
const Decl *d = gd.getDecl();
- didCallStackSave = false;
+ setDidCallStackSave(false);
curCodeDecl = d;
const auto *fd = dyn_cast_or_null<FunctionDecl>(d);
curFuncDecl = (d ? d->getNonClosureContext() : nullptr);
@@ -787,8 +787,8 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
fn->setAttr(cir::CIRDialect::getMustProgressAttrName(),
mlir::UnitAttr::get(&getMLIRContext()));
- if (shouldEmitLifetimeMarkers)
- fnHasBypassStmt = functionMightHaveBypass(body);
+ if (getShouldEmitLifetimeMarkers())
+ setFnHasBypassStmt(functionMightHaveBypass(body));
if (isa<CXXDestructorDecl>(funcDecl)) {
emitDestructorBody(args);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 8be794a660224..298c08f8b179d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -19,6 +19,7 @@
#include "CIRGenTypeCache.h"
#include "CIRGenValue.h"
#include "EHScopeStack.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "Address.h"
@@ -311,7 +312,7 @@ class CIRGenFunction : public CIRGenTypeCache {
mlir::Operation *curFn = nullptr;
/// Save Parameter Decl for coroutine.
- llvm::SmallVector<const ParmVarDecl *> fnArgs;
+ llvm::SmallVectorWithFlags<const ParmVarDecl *> fnArgs;
using DeclMapTy = llvm::DenseMap<const clang::Decl *, Address>;
/// This keeps track of the CIR allocas or globals for local C
@@ -319,7 +320,7 @@ class CIRGenFunction : public CIRGenTypeCache {
DeclMapTy localDeclMap;
/// The type of the condition for the emitting switch statement.
- llvm::SmallVector<mlir::Type, 2> condTypeStack;
+ llvm::SmallVectorWithFlags<mlir::Type, 2, 4> condTypeStack;
clang::ASTContext &getContext() const { return cgm.getASTContext(); }
@@ -368,15 +369,18 @@ class CIRGenFunction : public CIRGenTypeCache {
/// Whether a cir.stacksave operation has been added. Used to avoid
/// inserting cir.stacksave for multiple VLAs in the same scope.
- bool didCallStackSave = false;
+ bool getDidCallStackSave() const { return condTypeStack.getFlag(0); }
+ void setDidCallStackSave(bool Value) { condTypeStack.setFlag(0, Value); }
/// Whether or not a Microsoft-style asm block has been processed within
/// this fuction. These can potentially set the return value.
- bool sawAsmBlock = false;
+ bool getSawAsmBlock() const { return condTypeStack.getFlag(1); }
+ void setSawAsmBlock(bool Value) { condTypeStack.setFlag(1, Value); }
/// In C++, whether we are code generating a thunk. This controls whether we
/// should emit cleanups.
- bool curFuncIsThunk = false;
+ bool getCurFuncIsThunk() const { return condTypeStack.getFlag(2); }
+ void setCurFuncIsThunk(bool Value) { condTypeStack.setFlag(2, Value); }
mlir::Type convertTypeForMem(QualType t);
@@ -1375,8 +1379,8 @@ class CIRGenFunction : public CIRGenTypeCache {
cleanupStackDepth = cgf.ehStack.stable_begin();
lifetimeExtendedCleanupStackSize =
cgf.lifetimeExtendedCleanupStack.size();
- oldDidCallStackSave = cgf.didCallStackSave;
- cgf.didCallStackSave = false;
+ oldDidCallStackSave = cgf.getDidCallStackSave();
+ cgf.setDidCallStackSave(false);
oldCleanupStackDepth = cgf.currentCleanupStackDepth;
cgf.currentCleanupStackDepth = cleanupStackDepth;
}
@@ -1391,7 +1395,7 @@ class CIRGenFunction : public CIRGenTypeCache {
/// until this object is destroyed.
void forceCleanup(ArrayRef<mlir::Value *> valuesToReload = {}) {
assert(performCleanup && "Already forced cleanup");
- cgf.didCallStackSave = oldDidCallStackSave;
+ cgf.setDidCallStackSave(oldDidCallStackSave);
// forceDeactivate() can pop cleanup scopes that were pushed with
// deferred deactivation, which moves the insertion point out of the
@@ -1462,7 +1466,7 @@ class CIRGenFunction : public CIRGenTypeCache {
/// scope.
void forceCleanupExceptLifetimeExtended() {
assert(performCleanup && "Already forced cleanup");
- cgf.didCallStackSave = oldDidCallStackSave;
+ cgf.setDidCallStackSave(oldDidCallStackSave);
deactivateCleanups.forceDeactivate();
cgf.popCleanupBlocks(cleanupStackDepth);
}
@@ -3074,13 +3078,20 @@ class CIRGenFunction : public CIRGenTypeCache {
private:
QualType getVarArgType(const Expr *arg);
- bool shouldEmitLifetimeMarkers = false;
+ bool getShouldEmitLifetimeMarkers() const { return condTypeStack.getFlag(3); }
+ void setShouldEmitLifetimeMarkers(bool Value) {
+ condTypeStack.setFlag(3, Value);
+ }
/// Set when the current function has a goto/switch that may bypass a local's
/// init; lifetime markers are then suppressed. See functionMightHaveBypass.
- bool fnHasBypassStmt = false;
+ bool getFnHasBypassStmt() const { return fnArgs.getFlag(0); }
+ bool setFnHasBypassStmt(bool Value) {
+ fnArgs.setFlag(0, Value);
+ return Value;
+ }
bool shouldEmitLifetimeMarkersForAutoVar() const {
- return shouldEmitLifetimeMarkers && !fnHasBypassStmt;
+ return getShouldEmitLifetimeMarkers() && !getFnHasBypassStmt();
}
class InlinedInheritingConstructorScope {
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 614a731158e45..0bd2494c92e87 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -97,9 +97,9 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
// initializer function of their own only under the Itanium mangler, since
// no Microsoft mangling for it has been settled on yet; otherwise they fall
// back to `_GLOBAL__sub_I_` as in classic CodeGen.
- cxx20ModuleInits =
- langOpts.CPlusPlusModules &&
- getCXXABI().getMangleContext().getKind() == MangleContext::MK_Itanium;
+ setCxx20ModuleInits(langOpts.CPlusPlusModules &&
+ getCXXABI().getMangleContext().getKind() ==
+ MangleContext::MK_Itanium);
// Initialize cached types
voidTy = cir::VoidType::get(&getMLIRContext());
@@ -2556,7 +2556,7 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
// initializers are not emitted here. The global init function of this
// translation unit calls that initializer, which in turn covers the
// modules it imports itself; release() records the modules to call.
- if (cxx20ModuleInits && mod->isNamedModule())
+ if (getCxx20ModuleInits() && mod->isNamedModule())
break;
// For clang C++ module map modules the initializers for sub-modules are
@@ -2580,7 +2580,7 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
for (clang::Module *submodule : cur->submodules()) {
// Skip explicit children; they need to be explicitly imported to emit
// the initializers.
- if (submodule->IsExplicit)
+ if (submodule->getIsExplicit())
continue;
if (visited.insert(submodule).second)
@@ -4065,7 +4065,7 @@ void CIRGenModule::release() {
// and that the function needs external linkage, and its absence selects the
// `_GLOBAL__sub_I_` form. Lowering therefore never has to rediscover the
// module from the AST.
- if (cxx20ModuleInits) {
+ if (getCxx20ModuleInits()) {
clang::Module *primary = astContext.getCurrentNamedModule();
bool isInterfaceUnit = primary && !primary->isModuleImplementation();
if (isInterfaceUnit)
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 80bf5940e461e..ff3814cd90cf8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -21,6 +21,7 @@
#include "CIRGenTypes.h"
#include "CIRGenVTables.h"
#include "CIRGenValue.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "clang/AST/CharUnits.h"
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
@@ -116,11 +117,14 @@ class CIRGenModule : public CIRGenTypeCache {
llvm::SmallVector<mlir::Attribute> globalScopeAsm;
/// Accumulated record layout entries, materialized in release().
- llvm::SmallVector<mlir::NamedAttribute> recordLayoutEntries;
+ llvm::SmallVectorWithFlags<mlir::NamedAttribute> recordLayoutEntries;
/// Whether C++20 named modules get their own module initializer function,
/// which requires the Itanium mangling of the initializer name.
- bool cxx20ModuleInits = false;
+ bool getCxx20ModuleInits() const { return recordLayoutEntries.getFlag(0); }
+ void setCxx20ModuleInits(bool Value) {
+ recordLayoutEntries.setFlag(0, Value);
+ }
/// The complete set of modules that have been imported.
llvm::SetVector<clang::Module *> importedModules;
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index c2d39468782ce..5efa5b461d3e4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -14,6 +14,7 @@
#include "CIRGenModule.h"
#include "CIRGenTypes.h"
#include "TargetInfo.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -325,19 +326,32 @@ struct CIRRecordLowering final {
llvm::DenseMap<const CXXRecordDecl *, unsigned> virtualBases;
cir::CIRDataLayout dataLayout;
- LLVM_PREFERRED_TYPE(bool)
- unsigned zeroInitializable : 1;
- LLVM_PREFERRED_TYPE(bool)
- unsigned zeroInitializableAsBase : 1;
- LLVM_PREFERRED_TYPE(bool)
- unsigned packed : 1;
+ unsigned getZeroInitializable() const { return fieldKinds.getFlag(0); }
+ unsigned setZeroInitializable(unsigned Value) {
+ fieldKinds.setFlag(0, (Value & 1));
+ return (Value & 1);
+ }
+ unsigned getZeroInitializableAsBase() const { return fieldKinds.getFlag(1); }
+ unsigned setZeroInitializableAsBase(unsigned Value) {
+ fieldKinds.setFlag(1, (Value & 1));
+ return (Value & 1);
+ }
+ unsigned getPacked() const { return fieldKinds.getFlag(2); }
+ unsigned setPacked(unsigned Value) {
+ fieldKinds.setFlag(2, (Value & 1));
+ return (Value & 1);
+ }
private:
// Output fields, consumed by CIRGenTypes::computeRecordLayout. Private so
// that every append goes through addField and fieldKinds stays parallel to
// fieldTypes.
llvm::SmallVector<mlir::Type, 16> fieldTypes;
- llvm::SmallVector<cir::RecordMemberKind> fieldKinds;
+ llvm::SmallVectorWithFlags<cir::RecordMemberKind,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ cir::RecordMemberKind>::value,
+ 3>
+ fieldKinds;
CIRRecordLowering(const CIRRecordLowering &) = delete;
void operator=(const CIRRecordLowering &) = delete;
@@ -352,7 +366,8 @@ CIRRecordLowering::CIRRecordLowering(CIRGenTypes &cirGenTypes,
astRecordLayout{
cirGenTypes.getASTContext().getASTRecordLayout(recordDecl)},
dataLayout{cirGenTypes.getCGModule().getModule()},
- zeroInitializable{true}, zeroInitializableAsBase{true}, packed{packed} {}
+ fieldKinds(decltype(this->fieldKinds)::withFlags(
+ (unsigned((unsigned(packed) & 1)) << 2) | 3)) {}
void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
CharUnits startOffset,
@@ -780,21 +795,21 @@ void CIRRecordLowering::calculateZeroInit() {
if (member.kind == MemberInfo::InfoKind::Field) {
if (!member.fieldDecl || isZeroInitializable(member.fieldDecl))
continue;
- zeroInitializable = zeroInitializableAsBase = false;
+ setZeroInitializable(setZeroInitializableAsBase(false));
return;
} else if (member.kind == MemberInfo::InfoKind::Base ||
member.kind == MemberInfo::InfoKind::VBase) {
if (isZeroInitializable(member.cxxRecordDecl))
continue;
- zeroInitializable = false;
+ setZeroInitializable(false);
if (member.kind == MemberInfo::InfoKind::Base)
- zeroInitializableAsBase = false;
+ setZeroInitializableAsBase(false);
}
}
}
void CIRRecordLowering::determinePacked(bool nvBaseType) {
- if (packed)
+ if (getPacked())
return;
CharUnits alignment = CharUnits::One();
CharUnits nvAlignment = CharUnits::One();
@@ -810,7 +825,7 @@ void CIRRecordLowering::determinePacked(bool nvBaseType) {
// If any member falls at an offset that it not a multiple of its alignment,
// then the entire record must be packed.
if (!member.offset.isMultipleOf(getMemberAlignment(member.data)))
- packed = true;
+ setPacked(true);
if (member.offset < nvSize)
nvAlignment = std::max(nvAlignment, getMemberAlignment(member.data));
alignment = std::max(alignment, getMemberAlignment(member.data));
@@ -818,14 +833,14 @@ void CIRRecordLowering::determinePacked(bool nvBaseType) {
// If the size of the record (the capstone's offset) is not a multiple of the
// record's alignment, it must be packed.
if (!members.back().offset.isMultipleOf(alignment))
- packed = true;
+ setPacked(true);
// If the non-virtual sub-object is not a multiple of the non-virtual
// sub-object's alignment, it must be packed. We cannot have a packed
// non-virtual sub-object and an unpacked complete object or vise versa.
if (!nvSize.isMultipleOf(nvAlignment))
- packed = true;
+ setPacked(true);
// Update the alignment of the sentinel.
- if (!packed)
+ if (!getPacked())
members.back().data = getUIntNType(astContext.toBits(alignment));
}
@@ -850,8 +865,8 @@ void CIRRecordLowering::insertPadding() {
CharUnits offset = member.offset;
assert(offset >= size);
// Insert padding if we need to.
- if (offset != size.alignTo(packed ? CharUnits::One()
- : getMemberAlignment(member.data)))
+ if (offset != size.alignTo(getPacked() ? CharUnits::One()
+ : getMemberAlignment(member.data)))
padding.push_back(std::make_pair(size, offset - size));
size = offset + getSize(member.data);
}
@@ -913,12 +928,13 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) {
// union is empty, so a zero-data union does not spuriously qualify).
if (lowering.astRecordLayout.getNonVirtualSize() !=
lowering.astRecordLayout.getSize()) {
- CIRRecordLowering baseLowering(*this, rd, /*Packed=*/lowering.packed);
+ CIRRecordLowering baseLowering(*this, rd,
+ /*Packed=*/lowering.getPacked());
baseLowering.lower(/*nonVirtualBaseType=*/true);
std::string baseIdentifier = getRecordTypeName(rd, ".base");
baseTy = builder.getCompleteNamedRecordType(
- baseLowering.getFieldTypes(), baseLowering.packed, baseIdentifier,
- baseLowering.getFieldKinds());
+ baseLowering.getFieldTypes(), baseLowering.getPacked(),
+ baseIdentifier, baseLowering.getFieldKinds());
// TODO(cir): add something like addRecordTypeName
// BaseTy and Ty must agree on their packedness for getCIRFieldNo to work
@@ -927,8 +943,9 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) {
// base subobject but the full size for the complete object, so the two
// can legitimately disagree. (Classic CodeGen derives both from the data
// size and so needs no such exemption.)
- assert((rd->isUnion() || lowering.packed == baseLowering.packed) &&
- "Non-virtual and complete types must agree on packedness");
+ assert(
+ (rd->isUnion() || lowering.getPacked() == baseLowering.getPacked()) &&
+ "Non-virtual and complete types must agree on packedness");
// Emptiness is a property of the decl, so the base subobject must answer
// the same way the complete object does. The two are not comparable
// mark by mark: they see different sizes and so different tail padding.
@@ -942,8 +959,8 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) {
// signifies that the type is no longer opaque and record layout is complete,
// but we may need to recursively layout rd while laying D out as a base type.
assert(!cir::MissingFeatures::astRecordDeclAttr());
- ty->complete(lowering.getFieldTypes(), lowering.packed, lowering.unionPadding,
- lowering.getFieldKinds());
+ ty->complete(lowering.getFieldTypes(), lowering.getPacked(),
+ lowering.unionPadding, lowering.getFieldKinds());
// The marks exist so that emptiness can be read off the type, so check that
// answer against the AST predicate on every record CIRGen lays out. This
@@ -972,7 +989,8 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) {
auto rl = std::make_unique<CIRGenRecordLayout>(
ty ? *ty : cir::RecordType{}, baseTy ? baseTy : cir::RecordType{},
- (bool)lowering.zeroInitializable, (bool)lowering.zeroInitializableAsBase);
+ (bool)lowering.getZeroInitializable(),
+ (bool)lowering.getZeroInitializableAsBase());
rl->nonVirtualBases.swap(lowering.nonVirtualBases);
rl->completeObjectVirtualBases.swap(lowering.virtualBases);
@@ -1089,7 +1107,7 @@ void CIRRecordLowering::lowerUnion(bool nonVirtualBaseType) {
if (firstNamedMemberItr != recordDecl->fields().end() &&
!isZeroInitializable(*firstNamedMemberItr))
- zeroInitializable = zeroInitializableAsBase = false;
+ setZeroInitializable(setZeroInitializableAsBase(false));
// If we have no candidates for storage, we are JUST padding.
if (getFieldTypes().empty()) {
@@ -1129,7 +1147,7 @@ void CIRRecordLowering::lowerUnion(bool nonVirtualBaseType) {
// Else we just add padding normally.
appendPaddingBytes(layoutSize - getSize(storageType));
}
- packed = !layoutSize.isMultipleOf(getMemberAlignment(storageType));
+ setPacked(!layoutSize.isMultipleOf(getMemberAlignment(storageType)));
}
/// The AAPCS that defines that, when possible, bit-fields should
diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
index 270b8a6a539ba..27df6eb104efe 100644
--- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
@@ -648,7 +648,7 @@ void CIRGenFunction::startThunk(cir::FuncOp fn, GlobalDecl gd,
bool isUnprototyped) {
assert(!curGD.getDecl() && "curGD was already set!");
curGD = gd;
- curFuncIsThunk = true;
+ setCurFuncIsThunk(true);
// Build FunctionArgs.
const CXXMethodDecl *md = cast<CXXMethodDecl>(gd.getDecl());
diff --git a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
index aaacedeff1e74..c1f01ff8b777d 100644
--- a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
@@ -712,7 +712,7 @@ static std::optional<FunctionClassification> classifyX86_64Signature(
};
FunctionClassification fc;
- fc.returnsVoid = voidRet;
+ fc.setReturnsVoid(voidRet);
mlir::Type origRet = voidRet ? mlir::Type() : retCIR;
std::optional<ArgClassification> retAc =
convertABIArgInfo(fi->getReturnInfo(), ctx, origRet);
@@ -880,7 +880,7 @@ static std::optional<FunctionClassification>
withReturnVoidness(std::optional<FunctionClassification> fc,
mlir::Type returnType) {
if (fc)
- fc->returnsVoid = mlir::isa<cir::VoidType>(returnType);
+ fc->setReturnsVoid(mlir::isa<cir::VoidType>(returnType));
return fc;
}
diff --git a/clang/lib/CodeGen/BackendConsumer.h b/clang/lib/CodeGen/BackendConsumer.h
index 5337a5f7a1b4a..da16bb3b358e1 100644
--- a/clang/lib/CodeGen/BackendConsumer.h
+++ b/clang/lib/CodeGen/BackendConsumer.h
@@ -13,6 +13,7 @@
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/CodeGen/ModuleLinker.h"
#include "clang/CodeGenUtils/BackendDiagnosticHandler.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Timer.h"
@@ -35,13 +36,14 @@ class BackendConsumer : public ASTConsumer {
llvm::Timer LLVMIRGeneration;
unsigned LLVMIRGenerationRefCount = 0;
- bool TimerIsEnabled = false;
+ bool getTimerIsEnabled() const { return LinkModules.getFlag(0); }
+ void setTimerIsEnabled(bool Value) { LinkModules.setFlag(0, Value); }
BackendAction Action;
std::unique_ptr<CodeGenerator> Gen;
- SmallVector<LinkModule, 4> LinkModules;
+ llvm::SmallVectorWithFlags<LinkModule, 4> LinkModules;
// Translates LLVM backend diagnostics into clang diagnostics; shared with
// CIR so that both LLVM-emitting pipelines report backend diagnostics
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c93375ff3a18e..42971127111e8 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3382,14 +3382,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
// Nested builtin_preserve_access_index() not supported
- if (IsInPreservedAIRegion) {
+ if (getIsInPreservedAIRegion()) {
CGM.Error(E->getExprLoc(), "nested builtin_preserve_access_index() not supported");
return RValue::get(EmitScalarExpr(E->getArg(0)));
}
- IsInPreservedAIRegion = true;
+ setIsInPreservedAIRegion(true);
Value *Res = EmitScalarExpr(E->getArg(0));
- IsInPreservedAIRegion = false;
+ setIsInPreservedAIRegion(false);
return RValue::get(Res);
}
diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp
index ac2ed9a109c4f..bd2145658ecb2 100644
--- a/clang/lib/CodeGen/CGCUDANV.cpp
+++ b/clang/lib/CodeGen/CGCUDANV.cpp
@@ -20,6 +20,7 @@
#include "clang/Basic/Cuda.h"
#include "clang/CodeGen/CodeGenABITypes.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/Offloading/Utility.h"
#include "llvm/IR/BasicBlock.h"
@@ -85,9 +86,15 @@ class CGNVCUDARuntime : public CGCUDARuntime {
llvm::GlobalVariable *Shadow;
std::string DeviceName;
};
- llvm::SmallVector<OffloadProfSectionShadowInfo, 16> OffloadProfSectionShadows;
+ llvm::SmallVectorWithFlags<OffloadProfSectionShadowInfo, 16>
+ OffloadProfSectionShadows;
/// Whether we generate relocatable device code.
- bool RelocatableDeviceCode;
+ bool getRelocatableDeviceCode() const {
+ return OffloadProfSectionShadows.getFlag(0);
+ }
+ void setRelocatableDeviceCode(bool Value) {
+ OffloadProfSectionShadows.setFlag(0, Value);
+ }
/// Mangle context for device.
std::unique_ptr<MangleContext> DeviceMC;
@@ -247,7 +254,9 @@ static std::unique_ptr<MangleContext> InitDeviceMC(CodeGenModule &CGM) {
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM)
: CGCUDARuntime(CGM), Context(CGM.getLLVMContext()),
TheModule(CGM.getModule()),
- RelocatableDeviceCode(CGM.getLangOpts().GPURelocatableDeviceCode),
+ OffloadProfSectionShadows(
+ decltype(this->OffloadProfSectionShadows)::withFlags(
+ unsigned(bool(CGM.getLangOpts().GPURelocatableDeviceCode)))),
DeviceMC(InitDeviceMC(CGM)) {
IntTy = CGM.IntTy;
SizeTy = CGM.SizeTy;
@@ -849,15 +858,15 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
CGM.getCodeGenOpts().OffloadBinaryToEmbedFile;
if (CudaGpuBinaryFileName.empty() && !IsHIP)
return nullptr;
- if ((IsHIP || (IsCUDA && !RelocatableDeviceCode)) && EmittedKernels.empty() &&
- DeviceVars.empty())
+ if ((IsHIP || (IsCUDA && !getRelocatableDeviceCode())) &&
+ EmittedKernels.empty() && DeviceVars.empty())
return nullptr;
// void __{cuda|hip}_register_globals(void* handle);
llvm::Function *RegisterGlobalsFunc = makeRegisterGlobalsFn();
// We always need a function to pass in as callback. Create a dummy
// implementation if we don't need to register anything.
- if (RelocatableDeviceCode && !RegisterGlobalsFunc)
+ if (getRelocatableDeviceCode() && !RegisterGlobalsFunc)
RegisterGlobalsFunc = makeDummyFunction(getRegisterGlobalsFnTy());
// void ** __{cuda|hip}RegisterFatBinary(void *);
@@ -935,7 +944,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
FatMagic = HIPFatMagic;
} else {
- if (RelocatableDeviceCode)
+ if (getRelocatableDeviceCode())
FatbinConstantName = CGM.getTriple().isMacOSX()
? "__NV_CUDA,__nv_relfatbin"
: "__nv_relfatbin";
@@ -983,8 +992,9 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
// thread safety of the loaded program. Therefore we can assume sequential
// execution of constructor functions here.
if (IsHIP) {
- auto Linkage = RelocatableDeviceCode ? llvm::GlobalValue::ExternalLinkage
- : llvm::GlobalValue::InternalLinkage;
+ auto Linkage = getRelocatableDeviceCode()
+ ? llvm::GlobalValue::ExternalLinkage
+ : llvm::GlobalValue::InternalLinkage;
llvm::BasicBlock *IfBlock =
llvm::BasicBlock::Create(Context, "if", ModuleCtorFunc);
llvm::BasicBlock *ExitBlock =
@@ -994,8 +1004,8 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
GpuBinaryHandle = new llvm::GlobalVariable(
TheModule, PtrTy, /*isConstant=*/false, Linkage,
/*Initializer=*/
- !RelocatableDeviceCode ? llvm::ConstantPointerNull::get(PtrTy)
- : nullptr,
+ !getRelocatableDeviceCode() ? llvm::ConstantPointerNull::get(PtrTy)
+ : nullptr,
"__hip_gpubin_handle" + (CGM.getLangOpts().CUID.empty()
? ""
: "_" + CGM.getContext().getCUIDHash()));
@@ -1029,7 +1039,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
CtorBuilder.CreateCall(RegisterGlobalsFunc, HandleValue);
}
}
- } else if (!RelocatableDeviceCode) {
+ } else if (!getRelocatableDeviceCode()) {
// Register binary with CUDA runtime. This is substantially different in
// default mode vs. separate compilation!
// GpuBinaryHandle = __cudaRegisterFatBinary(&FatbinWrapper);
@@ -1492,7 +1502,7 @@ llvm::Function *CGNVCUDARuntime::finalizeModule() {
return nullptr;
}
if (!CGM.getLangOpts().CUDANVCCABI &&
- (CGM.getLangOpts().OffloadViaLLVM || RelocatableDeviceCode))
+ (CGM.getLangOpts().OffloadViaLLVM || getRelocatableDeviceCode()))
createOffloadingEntries();
else
return makeModuleCtorFunction();
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 1f4fd55060d39..ae3ff1a9efe05 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4478,7 +4478,7 @@ void CodeGenFunction::EmitFunctionEpilog(
// Reuse the debug location from the store unless there is
// cleanup code to be emitted between the store and return
// instruction.
- if (EmitRetDbgLoc && !AutoreleaseResult)
+ if (EmitRetDbgLoc && !getAutoreleaseResult())
RetDbgLoc = SI->getDebugLoc();
// Get the stored value and nuke the now-dead store.
RV = SI->getValueOperand();
@@ -4497,7 +4497,7 @@ void CodeGenFunction::EmitFunctionEpilog(
// In ARC, end functions that return a retainable type with a call
// to objc_autoreleaseReturnValue.
- if (AutoreleaseResult) {
+ if (getAutoreleaseResult()) {
#ifndef NDEBUG
// Type::isObjCRetainabletype has to be called on a QualType that hasn't
// been stripped of the typedefs, so we cannot use RetTy here. Get the
@@ -4722,7 +4722,7 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
}
// Deactivate the cleanup for the callee-destructed param that was pushed.
- if (type->isRecordType() && !CurFuncIsThunk &&
+ if (type->isRecordType() && !getCurFuncIsThunk() &&
type->castAsRecordDecl()->isParamDestroyedInCallee() &&
param->needsDestruction(getContext())) {
EHScopeStack::stable_iterator cleanup =
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 2901233638ffe..7f68ff493632c 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -27,6 +27,7 @@
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/CodeGenUtils/ClassUtils.h"
#include "clang/CodeGenUtils/RecordLayoutUtils.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -1005,7 +1006,7 @@ class ConstructorMemcpyizer : public FieldMemcpyizer {
// Returns true if a CXXCtorInitializer represents a member initialization
// that can be rolled into a memcpy.
bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const {
- if (!MemcpyableCtor)
+ if (!getMemcpyableCtor())
return false;
FieldDecl *Field = MemberInit->getMember();
assert(Field && "No field for member init.");
@@ -1032,10 +1033,10 @@ class ConstructorMemcpyizer : public FieldMemcpyizer {
FunctionArgList &Args)
: FieldMemcpyizer(CGF, CD->getParent(),
getTrivialCopySource(CGF, CD, Args)),
- ConstructorDecl(CD),
- MemcpyableCtor(CD->isDefaulted() && CD->isCopyOrMoveConstructor() &&
- CGF.getLangOpts().getGC() == LangOptions::NonGC),
- Args(Args) {}
+ ConstructorDecl(CD), Args(Args),
+ AggregatedInits(decltype(this->AggregatedInits)::withFlags(
+ unsigned(bool(CD->isDefaulted() && CD->isCopyOrMoveConstructor() &&
+ CGF.getLangOpts().getGC() == LangOptions::NonGC)))) {}
void addMemberInitializer(CXXCtorInitializer *MemberInit) {
if (isMemberInitMemcpyable(MemberInit)) {
@@ -1089,9 +1090,10 @@ class ConstructorMemcpyizer : public FieldMemcpyizer {
private:
const CXXConstructorDecl *ConstructorDecl;
- bool MemcpyableCtor;
+ bool getMemcpyableCtor() const { return AggregatedInits.getFlag(0); }
+ void setMemcpyableCtor(bool Value) { AggregatedInits.setFlag(0, Value); }
FunctionArgList &Args;
- SmallVector<CXXCtorInitializer *, 16> AggregatedInits;
+ llvm::SmallVectorWithFlags<CXXCtorInitializer *, 16> AggregatedInits;
};
class AssignmentMemcpyizer : public FieldMemcpyizer {
@@ -2910,7 +2912,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
llvm::Value *VTable,
CFITypeCheckKind TCK,
SourceLocation Loc) {
- assert(IsSanitizerScope);
+ assert(getIsSanitizerScope());
if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
!CGM.HasHiddenLTOVisibility(RD))
diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h
index fd8206fbccfe1..73ead570d8c75 100644
--- a/clang/lib/CodeGen/CGCleanup.h
+++ b/clang/lib/CodeGen/CGCleanup.h
@@ -14,6 +14,7 @@
#define LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
#include "EHScopeStack.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "Address.h"
#include "clang/CodeGenUtils/EHPersonality.h"
@@ -284,20 +285,21 @@ class alignas(8) EHCleanupScope : public EHScope {
/// Cleanups should mark these allocas as 'used' if the cleanup is
/// emitted, otherwise these instructions would be erased.
struct AuxillaryAllocas {
- SmallVector<llvm::Instruction *, 1> AuxAllocas;
- bool used = false;
+ llvm::SmallVectorWithFlags<llvm::Instruction *, 1> AuxAllocas;
+ bool getUsed() const { return AuxAllocas.getFlag(0); }
+ void setUsed(bool Value) { AuxAllocas.setFlag(0, Value); }
// Records a potentially unused instruction to be erased later.
void Add(llvm::AllocaInst *Alloca) { AuxAllocas.push_back(Alloca); }
// Mark all recorded instructions as used. These will not be erased later.
void MarkUsed() {
- used = true;
+ setUsed(true);
AuxAllocas.clear();
}
~AuxillaryAllocas() {
- if (used)
+ if (getUsed())
return;
llvm::SetVector<llvm::Instruction *> Uses;
for (auto *Inst : llvm::reverse(AuxAllocas))
diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp
index 2f162519139e0..a8e959a7abf87 100644
--- a/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/clang/lib/CodeGen/CGCoroutine.cpp
@@ -928,7 +928,7 @@ void CodeGenFunction::EmitCoroutineBody(const CoroutineBodyStmt &S) {
GetReturnObjectManager GroManager(*this, S);
CurCoro.Data->SuspendBB =
GroManager.DirectEmit ? RetBB : createBasicBlock("pre.gvo.conv");
- assert(ShouldEmitLifetimeMarkers &&
+ assert(getShouldEmitLifetimeMarkers() &&
"Must emit lifetime intrinsics for coroutines");
// Backend is allowed to elide memory allocations, to help it, emit
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 93428777b9b24..472e6cfa4c2d4 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -6976,11 +6976,11 @@ SanitizerDebugLocation::SanitizerDebugLocation(
SanitizerHandler Handler)
: CGF(CGF),
Apply(*CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler)) {
- assert(!CGF->IsSanitizerScope);
- CGF->IsSanitizerScope = true;
+ assert(!CGF->getIsSanitizerScope());
+ CGF->setIsSanitizerScope(true);
}
SanitizerDebugLocation::~SanitizerDebugLocation() {
- assert(CGF->IsSanitizerScope);
- CGF->IsSanitizerScope = false;
+ assert(CGF->getIsSanitizerScope());
+ CGF->setIsSanitizerScope(false);
}
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 019b7ac22272e..934e59a164ed9 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1366,7 +1366,7 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {
/// Emit a lifetime.begin marker if some criteria are satisfied.
/// \return whether the marker was emitted.
bool CodeGenFunction::EmitLifetimeStart(llvm::Value *Addr) {
- if (!ShouldEmitLifetimeMarkers)
+ if (!getShouldEmitLifetimeMarkers())
return false;
assert(Addr->getType()->getPointerAddressSpace() ==
@@ -1378,7 +1378,7 @@ bool CodeGenFunction::EmitLifetimeStart(llvm::Value *Addr) {
}
void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Addr) {
- if (!ShouldEmitLifetimeMarkers)
+ if (!getShouldEmitLifetimeMarkers())
return;
assert(Addr->getType()->getPointerAddressSpace() ==
@@ -1727,7 +1727,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
}
if (!VarAllocated) {
- if (!DidCallStackSave) {
+ if (!getDidCallStackSave()) {
// Save the stack.
Address Stack =
CreateDefaultAlignTempAlloca(AllocaInt8PtrTy, "saved_stack");
@@ -1736,7 +1736,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
assert(V->getType() == AllocaInt8PtrTy);
Builder.CreateStore(V, Stack);
- DidCallStackSave = true;
+ setDidCallStackSave(true);
// Push a cleanup block and restore the stack there.
// FIXME: in general circumstances, this should be an EH cleanup.
@@ -2810,7 +2810,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
// Push a destructor cleanup for this parameter if the ABI requires it.
// Don't push a cleanup in a thunk for a method that will also emit a
// cleanup.
- if (Ty->isRecordType() && !CurFuncIsThunk &&
+ if (Ty->isRecordType() && !getCurFuncIsThunk() &&
Ty->castAsRecordDecl()->isParamDestroyedInCallee()) {
if (QualType::DestructionKind DtorKind =
D.needsDestruction(getContext())) {
@@ -2844,7 +2844,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
LValue lv = MakeAddrLValue(DeclPtr, Ty);
// If this is a thunk, don't bother with ARC lifetime management.
// The true implementation will take care of that.
- if (IsScalar && !CurFuncIsThunk) {
+ if (IsScalar && !getCurFuncIsThunk()) {
Qualifiers qs = Ty.getQualifiers();
if (Qualifiers::ObjCLifetime lt = qs.getObjCLifetime()) {
// We honor __attribute__((ns_consumed)) for types with lifetime.
@@ -2927,7 +2927,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
// Emit debug info for param declarations in non-thunk functions.
if (CGDebugInfo *DI = getDebugInfo()) {
- if (CGM.getCodeGenOpts().hasReducedDebugInfo() && !CurFuncIsThunk &&
+ if (CGM.getCodeGenOpts().hasReducedDebugInfo() && !getCurFuncIsThunk() &&
!NoDebugInfo) {
llvm::DILocalVariable *DILocalVar = DI->EmitDeclareOfArgVariable(
&D, AllocaPtr.getPointer(), ArgNo, Builder, UseIndirectDebugAddress);
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 566f7e5d64f3e..cc2143b5103b1 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -838,7 +838,7 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
// When we import C++20 modules, we must run their initializers first.
SmallVector<llvm::Function *, 8> ModuleInits;
- if (CXX20ModuleInits)
+ if (getCXX20ModuleInits())
for (Module *M : CodeGenUtils::importedModulesToInitialize(
getContext().getCurrentNamedModule(),
ImportedModules.getArrayRef())) {
@@ -912,7 +912,7 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
// with priority emitted above. Module implementation units behave the same
// way as a non-modular TU with imports.
llvm::Function *Fn;
- if (CXX20ModuleInits && getContext().getCurrentNamedModule() &&
+ if (getCXX20ModuleInits() && getContext().getCurrentNamedModule() &&
!getContext().getCurrentNamedModule()->isModuleImplementation()) {
SmallString<256> InitFnName;
llvm::raw_svector_ostream Out(InitFnName);
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 78cc7ab2b8be0..43e181fb42ae9 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1598,7 +1598,7 @@ struct PerformSEHFinally final : EHScopeStack::Cleanup {
QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
llvm::Value *FP = nullptr;
// If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
- if (CGF.IsOutlinedSEHHelper) {
+ if (CGF.getIsOutlinedSEHHelper()) {
FP = &CGF.CurFn->arg_begin()[1];
} else {
llvm::Function *LocalAddrFn =
@@ -1941,7 +1941,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
llvm::Function *Fn = llvm::Function::Create(
FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
- IsOutlinedSEHHelper = true;
+ setIsOutlinedSEHHelper(true);
StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 927652c460922..3b510aeaf4460 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -622,7 +622,7 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
break;
case SD_FullExpression: {
- if (!ShouldEmitLifetimeMarkers)
+ if (!getShouldEmitLifetimeMarkers())
break;
// Avoid creating a conditional cleanup just to hold an llvm.lifetime.end
@@ -4355,7 +4355,7 @@ void CodeGenFunction::EmitCheck(
ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Checked,
SanitizerHandler CheckHandler, ArrayRef<llvm::Constant *> StaticArgs,
ArrayRef<llvm::Value *> DynamicArgs, const TrapReason *TR) {
- assert(IsSanitizerScope);
+ assert(getIsSanitizerScope());
assert(Checked.size() > 0);
assert(CheckHandler >= 0 &&
size_t(CheckHandler) < std::size(SanitizerHandlers));
@@ -5003,7 +5003,7 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
llvm::Value *eltPtr;
auto LastIndex = dyn_cast<llvm::ConstantInt>(indices.back());
if (!LastIndex ||
- (!CGF.IsInPreservedAIRegion && !IsPreserveAIArrayBase(CGF, Base))) {
+ (!CGF.getIsInPreservedAIRegion() && !IsPreserveAIArrayBase(CGF, Base))) {
addr = emitArraySubscriptGEP(CGF, addr, indices,
arrayType ? CGF.ConvertTypeForMem(*arrayType)
: nullptr,
@@ -6007,7 +6007,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
if (hasBPFPreserveStaticOffset(rec))
Addr = wrapWithBPFPreserveStaticOffset(*this, Addr);
if (!UseVolatile) {
- if (!IsInPreservedAIRegion &&
+ if (!getIsInPreservedAIRegion() &&
(!getDebugInfo() || !rec->hasAttr<BPFPreserveAccessIndexAttr>())) {
if (Idx != 0) {
// For structs, we GEP to the field that the record layout suggests.
@@ -6094,7 +6094,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
// a barrier every time CXXRecord field with vptr is referenced.
addr = Builder.CreateLaunderInvariantGroup(addr);
- if (IsInPreservedAIRegion ||
+ if (getIsInPreservedAIRegion() ||
(getDebugInfo() && rec->hasAttr<BPFPreserveAccessIndexAttr>())) {
// Remember the original union field index
llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateStandaloneType(base.getType(),
@@ -6109,7 +6109,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
if (FieldType->isReferenceType())
addr = addr.withElementType(CGM.getTypes().ConvertTypeForMem(FieldType));
} else {
- if (!IsInPreservedAIRegion &&
+ if (!getIsInPreservedAIRegion() &&
(!getDebugInfo() || !rec->hasAttr<BPFPreserveAccessIndexAttr>()))
// For structs, we GEP to the field that the record layout suggests.
addr = emitAddrOfFieldStorage(*this, addr, field, IsInBounds);
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index e2ec07bbae711..bc0c58e5e2264 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -29,6 +29,7 @@
#include "clang/CodeGenUtils/RecordLayoutUtils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
@@ -96,7 +97,7 @@ class ConstantAggregateBuilder : private ConstantAggregateBuilderUtils {
/// natural layout), but need not. Gaps between elements are implicitly
/// considered to be filled with undef.
llvm::SmallVector<llvm::Constant*, 32> Elems;
- llvm::SmallVector<CharUnits, 32> Offsets;
+ llvm::SmallVectorWithFlags<CharUnits, 32> Offsets;
/// The size of the constant (the maximum end offset of any added element).
/// May be larger than the end of Elems.back() if we split the last element
@@ -105,7 +106,11 @@ class ConstantAggregateBuilder : private ConstantAggregateBuilderUtils {
/// This is true only if laying out Elems in order as the elements of a
/// non-packed LLVM struct will give the correct layout.
- bool NaturalLayout = true;
+ bool getNaturalLayout() const { return !Offsets.getFlag(0); }
+ bool setNaturalLayout(bool Value) {
+ Offsets.setFlag(0, !Value);
+ return Value;
+ }
bool split(size_t Index, CharUnits Hint);
std::optional<size_t> splitAt(CharUnits Pos);
@@ -142,7 +147,7 @@ class ConstantAggregateBuilder : private ConstantAggregateBuilderUtils {
/// even if we can't represent it as that type.
llvm::Constant *build(llvm::Type *DesiredTy, bool AllowOversized) const {
return buildFrom(CGM, Elems, Offsets, CharUnits::Zero(), Size,
- NaturalLayout, DesiredTy, AllowOversized);
+ getNaturalLayout(), DesiredTy, AllowOversized);
}
};
@@ -160,7 +165,7 @@ bool ConstantAggregateBuilder::add(llvm::Constant *C, CharUnits Offset,
CharUnits Align = getAlignment(C);
CharUnits AlignedSize = Size.alignTo(Align);
if (AlignedSize > Offset || Offset.alignTo(Align) != Offset)
- NaturalLayout = false;
+ setNaturalLayout(false);
else if (AlignedSize < Offset) {
Elems.push_back(getPadding(Offset - Size));
Offsets.push_back(Size);
@@ -187,7 +192,7 @@ bool ConstantAggregateBuilder::add(llvm::Constant *C, CharUnits Offset,
replace(Elems, *FirstElemToReplace, *LastElemToReplace, {C});
replace(Offsets, *FirstElemToReplace, *LastElemToReplace, {Offset});
Size = std::max(Size, Offset + CSize);
- NaturalLayout = false;
+ setNaturalLayout(false);
return true;
}
@@ -327,7 +332,7 @@ std::optional<size_t> ConstantAggregateBuilder::splitAt(CharUnits Pos) {
/// Hint indicates the location at which we'd like to split, but may be
/// ignored.
bool ConstantAggregateBuilder::split(size_t Index, CharUnits Hint) {
- NaturalLayout = false;
+ setNaturalLayout(false);
llvm::Constant *C = Elems[Index];
CharUnits Offset = Offsets[Index];
@@ -1939,7 +1944,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
return CGM.EmitNullConstant(D.getType());
}
}
- InConstantContext = D.hasConstantInitialization();
+ setInConstantContext(D.hasConstantInitialization());
QualType destType = D.getType();
const Expr *E = D.getInit();
@@ -2126,7 +2131,8 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const Expr *E,
if (destType->isReferenceType())
Success = E->EvaluateAsLValue(Result, CGM.getContext());
else
- Success = E->EvaluateAsRValue(Result, CGM.getContext(), InConstantContext);
+ Success =
+ E->EvaluateAsRValue(Result, CGM.getContext(), isInConstantContext());
if (Success && !Result.HasSideEffects)
return tryEmitPrivate(Result.Val, destType);
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index db2b7a4ad1fce..539db62461104 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1909,7 +1909,7 @@ Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
void ScalarExprEmitter::EmitBinOpCheck(
ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
const BinOpInfo &Info) {
- assert(CGF.IsSanitizerScope);
+ assert(CGF.getIsSanitizerScope());
SanitizerHandler Check;
SmallVector<llvm::Constant *, 4> StaticData;
SmallVector<llvm::Value *, 2> DynamicData;
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index cb738d060c24a..219ac26301a2d 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1233,7 +1233,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
Builder.CreateStore(ivarVal, ReturnValue.withElementType(bitcastType));
// Make sure we don't do an autorelease.
- AutoreleaseResult = false;
+ setAutoreleaseResult(false);
return;
}
@@ -1290,7 +1290,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
EmitReturnOfRValue(RV, propType);
// objc_getProperty does an autorelease, so we should suppress ours.
- AutoreleaseResult = false;
+ setAutoreleaseResult(false);
return;
}
@@ -1356,7 +1356,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
} else
value = EmitLoadOfLValue(LV, SourceLocation()).getScalarVal();
- AutoreleaseResult = false;
+ setAutoreleaseResult(false);
}
value = Builder.CreateBitCast(
@@ -1777,7 +1777,7 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
// Emit .cxx_construct.
if (ctor) {
// Suppress the final autorelease in ARC.
- AutoreleaseResult = false;
+ setAutoreleaseResult(false);
for (const auto *IvarInit : IMP->inits()) {
FieldDecl *Field = IvarInit->getAnyMember();
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 7bfe0e0249407..d3b0b61da78cf 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -33,6 +33,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -2948,18 +2949,20 @@ class IvarLayoutBuilder {
CharUnits InstanceEnd;
/// Whether we're generating the strong layout or the weak layout.
- bool ForStrongLayout;
+ bool getForStrongLayout() const { return IvarsInfo.getFlag(0); }
+ void setForStrongLayout(bool Value) { IvarsInfo.setFlag(0, Value); }
/// Whether the offsets in IvarsInfo might be out-of-order.
- bool IsDisordered = false;
+ bool getIsDisordered() const { return IvarsInfo.getFlag(1); }
+ void setIsDisordered(bool Value) { IvarsInfo.setFlag(1, Value); }
- llvm::SmallVector<IvarInfo, 8> IvarsInfo;
+ llvm::SmallVectorWithFlags<IvarInfo, 8, 2> IvarsInfo;
public:
IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
CharUnits instanceEnd, bool forStrongLayout)
: CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
- ForStrongLayout(forStrongLayout) {}
+ IvarsInfo(decltype(IvarsInfo)::withFlags(unsigned(forStrongLayout))) {}
void visitRecord(const RecordType *RT, CharUnits offset);
@@ -3044,7 +3047,7 @@ void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {
// Block fields are not necessarily ordered; if we detect that we're
// adding them out-of-order, make sure we sort later.
if (fieldOffset < lastFieldOffset)
- IsDisordered = true;
+ setIsDisordered(true);
lastFieldOffset = fieldOffset;
// __block variables are passed by their descriptor address.
@@ -4693,7 +4696,7 @@ void CodeGenFunction::StartObjCDirectPreconditionThunk(
// call. Both hold whether we tail-call or not. Class realization could in
// theory invalidate parameters, but we assume that doesn't happen in
// practice.
- CurFuncIsThunk = true;
+ setCurFuncIsThunk(true);
// Build argument list for StartFunction.
// We must include all parameters to match the thunk's LLVM function type.
@@ -4732,7 +4735,7 @@ void CodeGenFunction::FinishObjCDirectPreconditionThunk() {
// Disable the final ARC autorelease.
// Thunk functions are tailcall to actual implementation, so it doesn't need
// to worry about ARC.
- AutoreleaseResult = false;
+ setAutoreleaseResult(false);
// Clear these to restore the invariants expected by
// StartFunction/FinishFunction.
@@ -6197,7 +6200,7 @@ void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
// If this is a union, remember that we had one, because it might mess
// up the ordering of layout entries.
if (RD->isUnion())
- IsDisordered = true;
+ setIsDisordered(true);
const ASTRecordLayout *recLayout = nullptr;
visitAggregate(RD->field_begin(), RD->field_end(), offset,
@@ -6281,8 +6284,8 @@ void IvarLayoutBuilder::visitField(const FieldDecl *field,
Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
// If it matches what we're looking for, add an entry.
- if ((ForStrongLayout && GCAttr == Qualifiers::Strong) ||
- (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
+ if ((getForStrongLayout() && GCAttr == Qualifiers::Strong) ||
+ (!getForStrongLayout() && GCAttr == Qualifiers::Weak)) {
assert(CGM.getContext().getTypeSizeInChars(fieldType) ==
CGM.getPointerSize());
IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
@@ -6305,7 +6308,7 @@ IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
// Sort the ivar info on byte position in case we encounterred a
// union nested in the ivar list.
- if (IsDisordered) {
+ if (getIsDisordered()) {
// This isn't a stable sort, but our algorithm should handle it fine.
llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
} else {
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index d24eac79f2ff1..24226e2e29959 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1062,7 +1062,7 @@ CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
// The user forces the compiler to behave as if omp requires
// unified_shared_memory was given.
if (CGM.getLangOpts().OpenMPForceUSM) {
- HasRequiresUnifiedSharedMemory = true;
+ setHasRequiresUnifiedSharedMemory(true);
OMPBuilder.Config.setHasRequiresUnifiedSharedMemory(true);
}
}
@@ -4049,7 +4049,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
FreeAgentFlag = 0x80,
TransparentFlag = 0x100,
};
- unsigned Flags = Data.Tied ? TiedFlag : 0;
+ unsigned Flags = Data.getTied() ? TiedFlag : 0;
bool NeedsCleanup = false;
if (!Privates.empty()) {
NeedsCleanup =
@@ -4874,7 +4874,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
}
auto &&ThenCodeGen = [this, &Data, TDBase, KmpTaskTQTyRD, &TaskArgs,
&DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
- if (!Data.Tied) {
+ if (!Data.getTied()) {
auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
LValue PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
@@ -4904,7 +4904,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
DepWaitTaskArgs[6] =
- llvm::ConstantInt::get(CGF.Int32Ty, Data.HasNowaitClause);
+ llvm::ConstantInt::get(CGF.Int32Ty, Data.getHasNowaitClause());
}
auto &M = CGM.getModule();
auto &&ElseCodeGen = [this, &M, &TaskArgs, ThreadID, NewTaskNewTaskTTy,
@@ -5026,7 +5026,7 @@ void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
? CGF.Builder.CreateIntCast(Data.Schedule.getPointer(), CGF.Int64Ty,
/*isSigned=*/false)
: llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0)};
- if (Data.HasModifier)
+ if (Data.getHasModifier())
TaskArgs.push_back(llvm::ConstantInt::get(CGF.Int32Ty, 1));
TaskArgs.push_back(Result.TaskDupFn
@@ -5034,7 +5034,7 @@ void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
Result.TaskDupFn, CGF.VoidPtrTy)
: llvm::ConstantPointerNull::get(CGF.VoidPtrTy));
CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
- CGM.getModule(), Data.HasModifier
+ CGM.getModule(), Data.getHasModifier()
? OMPRTL___kmpc_taskloop_5
: OMPRTL___kmpc_taskloop),
TaskArgs);
@@ -5509,8 +5509,8 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
if (!CGF.HaveInsertPoint())
return;
- bool WithNowait = Options.WithNowait;
- bool SimpleReduction = Options.SimpleReduction;
+ bool WithNowait = Options.getWithNowait();
+ bool SimpleReduction = Options.getSimpleReduction();
// Next code should be emitted for reduction:
//
@@ -6154,7 +6154,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit(
} else
CGF.EmitNullInitialization(FlagsLVal.getAddress(), FlagsLVal.getType());
}
- if (Data.IsReductionWithTaskMod) {
+ if (Data.getIsReductionWithTaskMod()) {
// Build call void *__kmpc_taskred_modifier_init(ident_t *loc, int gtid, int
// is_ws, int num, void *data);
llvm::Value *IdentTLoc = emitUpdateLocation(CGF, Loc);
@@ -6162,7 +6162,8 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit(
CGM.IntTy, /*isSigned=*/true);
llvm::Value *Args[] = {
IdentTLoc, GTid,
- llvm::ConstantInt::get(CGM.IntTy, Data.IsWorksharingReduction ? 1 : 0,
+ llvm::ConstantInt::get(CGM.IntTy,
+ Data.getIsWorksharingReduction() ? 1 : 0,
/*isSigned=*/true),
llvm::ConstantInt::get(CGM.IntTy, Size, /*isSigned=*/true),
CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
@@ -6264,7 +6265,7 @@ void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc,
DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
DepWaitTaskArgs[6] =
- llvm::ConstantInt::get(CGF.Int32Ty, Data.HasNowaitClause);
+ llvm::ConstantInt::get(CGF.Int32Ty, Data.getHasNowaitClause());
CodeGenFunction::RunCleanupsScope LocalScope(CGF);
@@ -6466,7 +6467,7 @@ void CGOpenMPRuntime::emitTargetOutlinedFunction(
llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
assert(!ParentName.empty() && "Invalid target entry parent name!");
- HasEmittedTargetRegion = true;
+ setHasEmittedTargetRegion(true);
SmallVector<std::pair<const Expr *, const Expr *>, 4> Allocators;
for (const auto *C : D.getClausesOfKind<OMPUsesAllocatorsClause>()) {
for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
@@ -8287,7 +8288,7 @@ class MappableExprsHandler {
// if the stride is not a constant expression (conservatively assumed
// non-contiguous).
bool IsNonContiguous =
- CombinedInfo.NonContigInfo.IsNonContiguous ||
+ CombinedInfo.NonContigInfo.getIsNonContiguous() ||
any_of(Components, [&](const auto &Component) {
const auto *OASE =
dyn_cast<ArraySectionExpr>(Component.getAssociatedExpression());
@@ -9458,8 +9459,8 @@ class MappableExprsHandler {
unsigned StructBasePointersIdx =
GroupStructBaseCurInfo.BasePointers.size();
- GroupCurInfo.NonContigInfo.IsNonContiguous =
- L.Components.back().isNonContiguous();
+ GroupCurInfo.NonContigInfo.setIsNonContiguous(
+ L.Components.back().isNonContiguous());
generateInfoForComponentList(
L.MapType, L.MapModifiers, L.MotionModifiers, L.Components,
GroupCurInfo, GroupStructBaseCurInfo, PartialStruct, AttachInfo,
@@ -11638,7 +11639,7 @@ bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link ||
((*Res == OMPDeclareTargetDeclAttr::MT_To ||
*Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
- HasRequiresUnifiedSharedMemory)) {
+ getHasRequiresUnifiedSharedMemory())) {
DeferredGlobalVariables.insert(cast<VarDecl>(GD.getDecl()));
return true;
}
@@ -11715,14 +11716,14 @@ void CGOpenMPRuntime::emitDeferredTargetDecls() const {
if (*Res == OMPDeclareTargetDeclAttr::MT_Local ||
((*Res == OMPDeclareTargetDeclAttr::MT_To ||
*Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
- !HasRequiresUnifiedSharedMemory)) {
+ !getHasRequiresUnifiedSharedMemory())) {
CGM.EmitGlobal(VD);
} else {
assert((*Res == OMPDeclareTargetDeclAttr::MT_Link ||
((*Res == OMPDeclareTargetDeclAttr::MT_To ||
*Res == OMPDeclareTargetDeclAttr::MT_Enter ||
*Res == OMPDeclareTargetDeclAttr::MT_Local) &&
- HasRequiresUnifiedSharedMemory)) &&
+ getHasRequiresUnifiedSharedMemory())) &&
"Expected link clause or to clause with unified memory.");
(void)CGM.getOpenMPRuntime().getAddrOfDeclareTargetVar(VD);
}
@@ -11738,7 +11739,7 @@ void CGOpenMPRuntime::adjustTargetSpecificDataForLambdas(
void CGOpenMPRuntime::processRequiresDirective(const OMPRequiresDecl *D) {
for (const OMPClause *Clause : D->clauselists()) {
if (Clause->getClauseKind() == OMPC_unified_shared_memory) {
- HasRequiresUnifiedSharedMemory = true;
+ setHasRequiresUnifiedSharedMemory(true);
OMPBuilder.Config.setHasRequiresUnifiedSharedMemory(true);
} else if (const auto *AC =
dyn_cast<OMPAtomicDefaultMemOrderClause>(Clause)) {
@@ -11789,25 +11790,28 @@ bool CGOpenMPRuntime::hasAllocateAttributeForGlobalVar(const VarDecl *VD,
}
bool CGOpenMPRuntime::hasRequiresUnifiedSharedMemory() const {
- return HasRequiresUnifiedSharedMemory;
+ return getHasRequiresUnifiedSharedMemory();
}
CGOpenMPRuntime::DisableAutoDeclareTargetRAII::DisableAutoDeclareTargetRAII(
CodeGenModule &CGM)
: CGM(CGM) {
if (CGM.getLangOpts().OpenMPIsTargetDevice) {
- SavedShouldMarkAsGlobal = CGM.getOpenMPRuntime().ShouldMarkAsGlobal;
- CGM.getOpenMPRuntime().ShouldMarkAsGlobal = false;
+ SavedShouldMarkAsGlobal = CGM.getOpenMPRuntime().getShouldMarkAsGlobal();
+ CGM.getOpenMPRuntime().setShouldMarkAsGlobal(false);
}
}
CGOpenMPRuntime::DisableAutoDeclareTargetRAII::~DisableAutoDeclareTargetRAII() {
if (CGM.getLangOpts().OpenMPIsTargetDevice)
- CGM.getOpenMPRuntime().ShouldMarkAsGlobal = SavedShouldMarkAsGlobal;
+ [&] {
+ auto PackedFlagValue = SavedShouldMarkAsGlobal;
+ return CGM.getOpenMPRuntime().setShouldMarkAsGlobal(PackedFlagValue);
+ }();
}
bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) {
- if (!CGM.getLangOpts().OpenMPIsTargetDevice || !ShouldMarkAsGlobal)
+ if (!CGM.getLangOpts().OpenMPIsTargetDevice || !getShouldMarkAsGlobal())
return true;
const auto *D = cast<FunctionDecl>(GD.getDecl());
@@ -12718,7 +12722,7 @@ void CGOpenMPRuntime::emitOutlinedFunctionCall(
void CGOpenMPRuntime::emitFunctionProlog(CodeGenFunction &CGF, const Decl *D) {
if (const auto *FD = dyn_cast<FunctionDecl>(D))
if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD))
- HasEmittedDeclareTargetRegion = true;
+ setHasEmittedDeclareTargetRegion(true);
}
Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
@@ -13568,7 +13572,7 @@ void CGOpenMPSIMDRuntime::emitReduction(
CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> Privates,
ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
ArrayRef<const Expr *> ReductionOps, ReductionOptionsTy Options) {
- assert(Options.SimpleReduction && "Only simple reduction is expected.");
+ assert(Options.getSimpleReduction() && "Only simple reduction is expected.");
CGOpenMPRuntime::emitReduction(CGF, Loc, Privates, LHSExprs, RHSExprs,
ReductionOps, Options);
}
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h
index ae55295cadc14..2ced2b6238b54 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -22,6 +22,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -102,7 +103,8 @@ struct OMPTaskDataTy final {
SmallVector<const Expr *, 4> ReductionOrigs;
SmallVector<const Expr *, 4> ReductionCopies;
SmallVector<const Expr *, 4> ReductionOps;
- SmallVector<CanonicalDeclPtr<const VarDecl>, 4> PrivateLocals;
+ llvm::SmallVectorWithFlags<CanonicalDeclPtr<const VarDecl>, 4, 2>
+ PrivateLocals;
struct DependData {
OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
const Expr *IteratorExpr = nullptr;
@@ -111,18 +113,24 @@ struct OMPTaskDataTy final {
DependData(OpenMPDependClauseKind DepKind, const Expr *IteratorExpr)
: DepKind(DepKind), IteratorExpr(IteratorExpr) {}
};
- SmallVector<DependData, 4> Dependences;
+ llvm::SmallVectorWithFlags<DependData, 4, 4> Dependences;
llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule;
llvm::PointerIntPair<llvm::Value *, 1, bool> Priority;
llvm::Value *Reductions = nullptr;
unsigned NumberOfParts = 0;
- bool Tied = true;
- bool Nogroup = false;
- bool IsReductionWithTaskMod = false;
- bool IsWorksharingReduction = false;
- bool HasNowaitClause = false;
- bool HasModifier = false;
+ bool getTied() const { return !Dependences.getFlag(0); }
+ void setTied(bool Value) { Dependences.setFlag(0, !Value); }
+ bool getNogroup() const { return Dependences.getFlag(1); }
+ void setNogroup(bool Value) { Dependences.setFlag(1, Value); }
+ bool getIsReductionWithTaskMod() const { return Dependences.getFlag(2); }
+ void setIsReductionWithTaskMod(bool Value) { Dependences.setFlag(2, Value); }
+ bool getIsWorksharingReduction() const { return Dependences.getFlag(3); }
+ void setIsWorksharingReduction(bool Value) { Dependences.setFlag(3, Value); }
+ bool getHasNowaitClause() const { return PrivateLocals.getFlag(0); }
+ void setHasNowaitClause(bool Value) { PrivateLocals.setFlag(0, Value); }
+ bool getHasModifier() const { return PrivateLocals.getFlag(1); }
+ void setHasModifier(bool Value) { PrivateLocals.setFlag(1, Value); }
};
/// Class intended to support codegen of all kind of the reduction clauses.
@@ -477,7 +485,13 @@ class CGOpenMPRuntime {
/// };
QualType KmpDimTy;
- bool ShouldMarkAsGlobal = true;
+ bool getShouldMarkAsGlobal() const {
+ return !LastprivateConditionalStack.getFlag(0);
+ }
+ bool setShouldMarkAsGlobal(bool Value) {
+ LastprivateConditionalStack.setFlag(0, !Value);
+ return Value;
+ }
/// List of the emitted declarations.
llvm::DenseSet<CanonicalDeclPtr<const Decl>> AlreadyEmittedTargetDecls;
/// List of the global variables with their addresses that should not be
@@ -501,21 +515,38 @@ class CGOpenMPRuntime {
/// Stack for list of addresses of declarations in current context marked as
/// lastprivate conditional. The set is the union of all current stack
/// elements.
- llvm::SmallVector<LastprivateConditionalData, 4> LastprivateConditionalStack;
+ llvm::SmallVectorWithFlags<LastprivateConditionalData, 4, 4>
+ LastprivateConditionalStack;
/// Flag for keeping track of weather a requires unified_shared_memory
/// directive is present.
- bool HasRequiresUnifiedSharedMemory = false;
+ bool getHasRequiresUnifiedSharedMemory() const {
+ return LastprivateConditionalStack.getFlag(1);
+ }
+ void setHasRequiresUnifiedSharedMemory(bool Value) {
+ LastprivateConditionalStack.setFlag(1, Value);
+ }
/// Atomic ordering from the omp requires directive.
llvm::AtomicOrdering RequiresAtomicOrdering = llvm::AtomicOrdering::Monotonic;
/// Flag for keeping track of weather a target region has been emitted.
- bool HasEmittedTargetRegion = false;
+ bool getHasEmittedTargetRegion() const {
+ return LastprivateConditionalStack.getFlag(2);
+ }
+ void setHasEmittedTargetRegion(bool Value) {
+ LastprivateConditionalStack.setFlag(2, Value);
+ }
/// Flag for keeping track of weather a device routine has been emitted.
/// Device routines are specific to the
- bool HasEmittedDeclareTargetRegion = false;
+ bool getHasEmittedDeclareTargetRegion() const {
+ return LastprivateConditionalStack.getFlag(3);
+ }
+ bool setHasEmittedDeclareTargetRegion(bool Value) {
+ LastprivateConditionalStack.setFlag(3, Value);
+ return Value;
+ }
/// Start scanning from statement \a S and emit all target regions
/// found along the way.
@@ -1245,9 +1276,21 @@ class CGOpenMPRuntime {
const DeclRefExpr *RHS);
struct ReductionOptionsTy {
- bool WithNowait;
- bool SimpleReduction;
- llvm::SmallVector<bool, 8> IsPrivateVarReduction;
+ ReductionOptionsTy(bool WithNowait, bool SimpleReduction,
+ llvm::SmallVector<bool, 8> IsPrivateVarReduction,
+ OpenMPDirectiveKind ReductionKind)
+ : IsPrivateVarReduction(unsigned(WithNowait) |
+ (unsigned(SimpleReduction) << 1),
+ std::move(IsPrivateVarReduction)),
+ ReductionKind(ReductionKind) {}
+
+ bool getWithNowait() const { return IsPrivateVarReduction.getFlag(0); }
+ void setWithNowait(bool Value) { IsPrivateVarReduction.setFlag(0, Value); }
+ bool getSimpleReduction() const { return IsPrivateVarReduction.getFlag(1); }
+ void setSimpleReduction(bool Value) {
+ IsPrivateVarReduction.setFlag(1, Value);
+ }
+ llvm::SmallVectorWithFlags<bool, 8, 2> IsPrivateVarReduction;
OpenMPDirectiveKind ReductionKind;
};
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index e7322bdd0deca..6deceda66a07b 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -1768,7 +1768,7 @@ void CGOpenMPRuntimeGPU::emitReduction(
bool ParallelReduction = isOpenMPParallelDirective(Options.ReductionKind);
bool TeamsReduction = isOpenMPTeamsDirective(Options.ReductionKind);
- if (Options.SimpleReduction) {
+ if (Options.getSimpleReduction()) {
assert(!TeamsReduction && !ParallelReduction &&
"Invalid reduction selection in emitReduction.");
(void)ParallelReduction;
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 0a5fd222b7d80..6364179fd9cd3 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -23,6 +23,7 @@
#include "clang/Basic/CodeGenOptions.h"
#include "clang/CodeGenUtils/RecordLayoutUtils.h"
#include "clang/CodeGenUtils/TargetUtils.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
@@ -191,14 +192,24 @@ struct CGRecordLowering {
// Helpful intermediate data-structures.
std::vector<MemberInfo> Members;
// Output fields, consumed by CodeGenTypes::ComputeRecordLayout.
- SmallVector<llvm::Type *, 16> FieldTypes;
+ llvm::SmallVectorWithFlags<llvm::Type *, 16, 3> FieldTypes;
llvm::DenseMap<const FieldDecl *, unsigned> Fields;
llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
llvm::DenseMap<const CXXRecordDecl *, unsigned> VirtualBases;
- bool IsZeroInitializable : 1;
- bool IsZeroInitializableAsBase : 1;
- bool Packed : 1;
+ bool getIsZeroInitializable() const { return FieldTypes.getFlag(0); }
+ void setIsZeroInitializable(bool Value) { FieldTypes.setFlag(0, Value); }
+ bool getIsZeroInitializableAsBase() const { return FieldTypes.getFlag(1); }
+ bool setIsZeroInitializableAsBase(bool Value) {
+ FieldTypes.setFlag(1, Value);
+ return Value;
+ }
+ bool getPacked() const { return FieldTypes.getFlag(2); }
+ bool setPacked(bool Value) {
+ FieldTypes.setFlag(2, Value);
+ return Value;
+ }
+
private:
CGRecordLowering(const CGRecordLowering &) = delete;
void operator =(const CGRecordLowering &) = delete;
@@ -210,8 +221,9 @@ CGRecordLowering::CGRecordLowering(CodeGenTypes &Types, const RecordDecl *D,
: Types(Types), Context(Types.getContext()), D(D),
RD(dyn_cast<CXXRecordDecl>(D)),
Layout(Types.getContext().getASTRecordLayout(D)),
- DataLayout(Types.getDataLayout()), IsZeroInitializable(true),
- IsZeroInitializableAsBase(true), Packed(Packed) {}
+ DataLayout(Types.getDataLayout()),
+ FieldTypes(
+ decltype(this->FieldTypes)::withFlags((unsigned(Packed) << 2) | 3)) {}
void CGRecordLowering::setBitFieldInfo(
const FieldDecl *FD, CharUnits StartOffset, llvm::Type *StorageType) {
@@ -324,13 +336,13 @@ void CGRecordLowering::lowerUnion(bool isNonVirtualBaseType) {
if (const auto *FieldRD = Field->getType()->getAsRecordDecl())
SeenNamedMember = FieldRD->findFirstNamedDataMember();
if (SeenNamedMember && !isZeroInitializable(Field)) {
- IsZeroInitializable = IsZeroInitializableAsBase = false;
+ setIsZeroInitializable(setIsZeroInitializableAsBase(false));
StorageType = FieldType;
}
}
// Because our union isn't zero initializable, we won't be getting a better
// storage type.
- if (!IsZeroInitializable)
+ if (!getIsZeroInitializable())
continue;
// Conditionally update our storage type if we've got a new "better" one.
if (!StorageType ||
@@ -355,7 +367,7 @@ void CGRecordLowering::lowerUnion(bool isNonVirtualBaseType) {
"Union's standard layout and no_unique_address layout must agree on "
"packedness");
if (!Layout.getDataSize().isMultipleOf(StorageAlignment))
- Packed = true;
+ setPacked(true);
}
void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) {
@@ -903,18 +915,18 @@ void CGRecordLowering::accumulateVBases() {
void CGRecordLowering::calculateZeroInit() {
for (std::vector<MemberInfo>::const_iterator Member = Members.begin(),
MemberEnd = Members.end();
- IsZeroInitializableAsBase && Member != MemberEnd; ++Member) {
+ getIsZeroInitializableAsBase() && Member != MemberEnd; ++Member) {
if (Member->Kind == MemberInfo::Field) {
if (!Member->FD || isZeroInitializable(Member->FD))
continue;
- IsZeroInitializable = IsZeroInitializableAsBase = false;
+ setIsZeroInitializable(setIsZeroInitializableAsBase(false));
} else if (Member->Kind == MemberInfo::Base ||
Member->Kind == MemberInfo::VBase) {
if (isZeroInitializable(Member->RD))
continue;
- IsZeroInitializable = false;
+ setIsZeroInitializable(false);
if (Member->Kind == MemberInfo::Base)
- IsZeroInitializableAsBase = false;
+ setIsZeroInitializableAsBase(false);
}
}
}
@@ -938,7 +950,7 @@ void CGRecordLowering::checkBitfieldClipping(bool IsNonVirtualBaseType) const {
}
void CGRecordLowering::determinePacked(bool NVBaseType) {
- if (Packed)
+ if (getPacked())
return;
CharUnits Alignment = CharUnits::One();
CharUnits NVAlignment = CharUnits::One();
@@ -950,7 +962,7 @@ void CGRecordLowering::determinePacked(bool NVBaseType) {
// If any member falls at an offset that it not a multiple of its alignment,
// then the entire record must be packed.
if (!Member.Offset.isMultipleOf(getAlignment(Member.Data)))
- Packed = true;
+ setPacked(true);
if (Member.Offset < NVSize)
NVAlignment = std::max(NVAlignment, getAlignment(Member.Data));
Alignment = std::max(Alignment, getAlignment(Member.Data));
@@ -958,14 +970,14 @@ void CGRecordLowering::determinePacked(bool NVBaseType) {
// If the size of the record (the capstone's offset) is not a multiple of the
// record's alignment, it must be packed.
if (!Members.back().Offset.isMultipleOf(Alignment))
- Packed = true;
+ setPacked(true);
// If the non-virtual sub-object is not a multiple of the non-virtual
// sub-object's alignment, it must be packed. We cannot have a packed
// non-virtual sub-object and an unpacked complete object or vise versa.
if (!NVSize.isMultipleOf(NVAlignment))
- Packed = true;
+ setPacked(true);
// Update the alignment of the sentinel.
- if (!Packed)
+ if (!getPacked())
Members.back().Data = getIntNType(Context.toBits(Alignment));
}
@@ -978,8 +990,8 @@ void CGRecordLowering::insertPadding() {
CharUnits Offset = Member.Offset;
assert(Offset >= Size);
// Insert padding if we need to.
- if (Offset !=
- Size.alignTo(Packed ? CharUnits::One() : getAlignment(Member.Data)))
+ if (Offset != Size.alignTo(getPacked() ? CharUnits::One()
+ : getAlignment(Member.Data)))
Padding.push_back(std::make_pair(Size, Offset - Size));
Size = Offset + getSize(Member.Data);
}
@@ -1061,14 +1073,15 @@ CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty) {
if (isa<CXXRecordDecl>(D)) {
BaseTy = Ty;
if (Builder.Layout.getNonVirtualSize() != Builder.Layout.getSize()) {
- CGRecordLowering BaseBuilder(*this, D, /*Packed=*/Builder.Packed);
+ CGRecordLowering BaseBuilder(*this, D, /*Packed=*/Builder.getPacked());
BaseBuilder.lower(/*NonVirtualBaseType=*/true);
- BaseTy = llvm::StructType::create(
- getLLVMContext(), BaseBuilder.FieldTypes, "", BaseBuilder.Packed);
+ BaseTy =
+ llvm::StructType::create(getLLVMContext(), BaseBuilder.FieldTypes, "",
+ BaseBuilder.getPacked());
addRecordTypeName(D, BaseTy, ".base");
// BaseTy and Ty must agree on their packedness for getLLVMFieldNo to work
// on both of them with the same index.
- assert(Builder.Packed == BaseBuilder.Packed &&
+ assert(Builder.getPacked() == BaseBuilder.getPacked() &&
"Non-virtual and complete types must agree on packedness");
}
}
@@ -1076,11 +1089,11 @@ CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty) {
// Fill in the struct *after* computing the base type. Filling in the body
// signifies that the type is no longer opaque and record layout is complete,
// but we may need to recursively layout D while laying D out as a base type.
- Ty->setBody(Builder.FieldTypes, Builder.Packed);
+ Ty->setBody(Builder.FieldTypes, Builder.getPacked());
auto RL = std::make_unique<CGRecordLayout>(
- Ty, BaseTy, (bool)Builder.IsZeroInitializable,
- (bool)Builder.IsZeroInitializableAsBase);
+ Ty, BaseTy, (bool)Builder.getIsZeroInitializable(),
+ (bool)Builder.getIsZeroInitializableAsBase());
RL->NonVirtualBases.swap(Builder.NonVirtualBases);
RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases);
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 05b3693138b0a..84f3352df7409 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -30,6 +30,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Assumptions.h"
#include "llvm/IR/DataLayout.h"
@@ -1586,7 +1587,7 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
}
// Returning from an outlined SEH helper is UB, and we already warn on it.
- if (IsOutlinedSEHHelper) {
+ if (getIsOutlinedSEHHelper()) {
Builder.CreateUnreachable();
Builder.ClearInsertionPoint();
}
@@ -2675,7 +2676,7 @@ class AsmConstraintsInfo {
// Destination blocks for 'asm gotos'.
llvm::BasicBlock *DefaultDest = nullptr;
- SmallVector<llvm::BasicBlock *, 3> IndirectDests;
+ llvm::SmallVectorWithFlags<llvm::BasicBlock *, 3, 2> IndirectDests;
std::vector<std::optional<std::pair<unsigned, unsigned>>> ResultBounds;
@@ -2688,8 +2689,10 @@ class AsmConstraintsInfo {
//
// It can be marked readnone if it doesn't have any input memory
// constraints in addition to meeting the conditions listed above.
- bool ReadOnly = true;
- bool ReadNone = true;
+ bool getReadOnly() const { return !IndirectDests.getFlag(0); }
+ void setReadOnly(bool Value) { IndirectDests.setFlag(0, !Value); }
+ bool getReadNone() const { return !IndirectDests.getFlag(1); }
+ void setReadNone(bool Value) { IndirectDests.setFlag(1, !Value); }
bool GetOutputAndInputConstraints();
void HandleOutputConstraints();
@@ -3023,8 +3026,8 @@ void AsmConstraintsInfo::HandleOutputConstraints() {
Args.push_back(DestAddr.emitRawPointer(CGF));
Constraints += "=*" + OutputConstraint;
- ReadOnly = false;
- ReadNone = false;
+ setReadOnly(false);
+ setReadNone(false);
}
if (!Info.isReadWrite())
@@ -3078,7 +3081,7 @@ void AsmConstraintsInfo::HandleMSStyleAsmBlob() {
CGM.getTargetCodeGenInfo().addReturnRegisterOutputs(
CGF, ReturnSlot, Constraints, ResultRegTypes, ResultTruncRegTypes,
ResultRegDests, AsmString, S.getNumOutputs());
- CGF.SawAsmBlock = true;
+ CGF.setSawAsmBlock(true);
}
/// Process the input constraints of an inline assembly statement. It handles
@@ -3092,7 +3095,7 @@ void AsmConstraintsInfo::HandleInputConstraints() {
const Expr *InputExpr = S.getInputExpr(I);
if (Info.allowsMemory())
- ReadNone = false;
+ setReadNone(false);
if (!Constraints.empty())
Constraints += ',';
@@ -3209,8 +3212,8 @@ bool AsmConstraintsInfo::HandleClobbers() {
}
if (Clobber == "memory") {
- ReadOnly = false;
- ReadNone = false;
+ setReadOnly(false);
+ setReadNone(false);
} else if (Clobber != "cc") {
Clobber = getTarget().getNormalizedGCCRegisterName(Clobber);
if (CGM.getCodeGenOpts().StackClashProtector &&
@@ -3260,9 +3263,9 @@ void AsmConstraintsInfo::UpdateAsmCallInst(
// Attach readnone and readonly attributes.
if (!HasSideEffect) {
- if (ReadNone)
+ if (getReadNone())
Result.setDoesNotAccessMemory();
- else if (ReadOnly)
+ else if (getReadOnly())
Result.setOnlyReadsMemory();
}
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index b8fdcee65bf93..adecf1bb8957c 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1829,8 +1829,8 @@ void CodeGenFunction::EmitOMPReductionClauseInit(
}
if (!Data.ReductionVars.empty()) {
OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(D);
- Data.IsReductionWithTaskMod = true;
- Data.IsWorksharingReduction = isOpenMPWorksharingDirective(EKind);
+ Data.setIsReductionWithTaskMod(true);
+ Data.setIsWorksharingReduction(isOpenMPWorksharingDirective(EKind));
llvm::Value *ReductionDesc = CGM.getOpenMPRuntime().emitTaskReductionInit(
*this, D.getBeginLoc(), TaskLHSs, TaskRHSs, Data);
const Expr *TaskRedRef = nullptr;
@@ -3417,7 +3417,7 @@ static void emitOMPSimdDirective(const OMPLoopDirective &S,
}
CodeGenFunction::ParentLoopDirectiveForScanRegion ScanRegion(CGF, S);
- CGF.OMPFirstScanLoop = true;
+ CGF.setOMPFirstScanLoop(true);
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
emitOMPSimdRegion(CGF, S, Action);
};
@@ -4439,7 +4439,7 @@ static void emitScanBasedDirective(
// <input phase>;
// buffer[i] = red;
// }
- CGF.OMPFirstScanLoop = true;
+ CGF.setOMPFirstScanLoop(true);
CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
FirstGen(CGF);
}
@@ -4548,7 +4548,7 @@ static void emitScanBasedDirective(
RCG(CGF);
}
- CGF.OMPFirstScanLoop = false;
+ CGF.setOMPFirstScanLoop(false);
SecondGen(CGF);
}
@@ -5529,7 +5529,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
// Build list of dependences.
buildDependences(S, Data);
// Get list of local vars for untied tasks.
- if (!Data.Tied) {
+ if (!Data.getTied()) {
CheckVarsEscapingUntiedTaskDeclContext Checker;
Checker.Visit(S.getInnermostCapturedStmt()->getCapturedStmt());
Data.PrivateLocals.append(Checker.getPrivateDecls().begin(),
@@ -5833,7 +5833,8 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
};
OpenMPDirectiveKind EKind = getEffectiveDirectiveKind(S);
llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
- S, *I, *PartId, *TaskT, EKind, CodeGen, Data.Tied, Data.NumberOfParts);
+ S, *I, *PartId, *TaskT, EKind, CodeGen, Data.getTied(),
+ Data.NumberOfParts);
OMPLexicalScope Scope(*this, S, std::nullopt,
!isOpenMPParallelDirective(EKind) &&
!isOpenMPSimdDirective(EKind));
@@ -6124,7 +6125,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
OMPTaskDataTy Data;
// Check if we should emit tied or untied task.
- Data.Tied = !S.getSingleClause<OMPUntiedClause>();
+ Data.setTied(!S.getSingleClause<OMPUntiedClause>());
auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
CGF.EmitStmt(CS->getCapturedStmt());
};
@@ -6163,7 +6164,7 @@ void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
OMPTaskDataTy Data;
// Build list of dependences
buildDependences(S, Data);
- Data.HasNowaitClause = S.hasClausesOfKind<OMPNowaitClause>();
+ Data.setHasNowaitClause(S.hasClausesOfKind<OMPNowaitClause>());
CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getBeginLoc(), Data);
}
@@ -6389,7 +6390,7 @@ void CodeGenFunction::EmitOMPScanDirective(const OMPScanDirective &S) {
EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
EmitBlock(OMPScanExitBlock);
}
- if (OMPFirstScanLoop) {
+ if (getOMPFirstScanLoop()) {
// Emit buffer[i] = red; at the end of the input phase.
const auto *IVExpr = cast<OMPLoopDirective>(ParentDir)
.getIterationVariable()
@@ -6420,7 +6421,7 @@ void CodeGenFunction::EmitOMPScanDirective(const OMPScanDirective &S) {
EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
}
EmitBlock(OMPScanDispatch);
- if (!OMPFirstScanLoop) {
+ if (!getOMPFirstScanLoop()) {
// Emit red = buffer[i]; at the entrance to the scan phase.
const auto *IVExpr = cast<OMPLoopDirective>(ParentDir)
.getIterationVariable()
@@ -6458,8 +6459,8 @@ void CodeGenFunction::EmitOMPScanDirective(const OMPScanDirective &S) {
EmitBlock(ExclusiveExitBB);
}
}
- EmitBranch((OMPFirstScanLoop == IsInclusive) ? OMPBeforeScanBlock
- : OMPAfterScanBlock);
+ EmitBranch((getOMPFirstScanLoop() == IsInclusive) ? OMPBeforeScanBlock
+ : OMPAfterScanBlock);
EmitBlock(OMPAfterScanBlock);
}
@@ -7941,12 +7942,13 @@ void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) {
S.getBeginLoc());
DependenceList = DependenciesArray.emitRawPointer(*this);
}
- Data.HasNowaitClause = S.hasClausesOfKind<OMPNowaitClause>();
+ Data.setHasNowaitClause(S.hasClausesOfKind<OMPNowaitClause>());
- assert(!(Data.HasNowaitClause && !(S.getSingleClause<OMPInitClause>() ||
- S.getSingleClause<OMPDestroyClause>() ||
- S.getSingleClause<OMPUseClause>())) &&
- "OMPNowaitClause clause is used separately in OMPInteropDirective.");
+ assert(
+ !(Data.getHasNowaitClause() && !(S.getSingleClause<OMPInitClause>() ||
+ S.getSingleClause<OMPDestroyClause>() ||
+ S.getSingleClause<OMPUseClause>())) &&
+ "OMPNowaitClause clause is used separately in OMPInteropDirective.");
auto ItOMPInitClause = S.getClausesOfKind<OMPInitClause>();
if (!ItOMPInitClause.empty()) {
@@ -7965,7 +7967,7 @@ void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) {
}
OMPBuilder.createOMPInteropInit(Builder, InteropvarPtr, InteropType,
Device, NumDependences, DependenceList,
- Data.HasNowaitClause);
+ Data.getHasNowaitClause());
}
}
auto ItOMPDestroyClause = S.getClausesOfKind<OMPDestroyClause>();
@@ -7976,7 +7978,7 @@ void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) {
EmitLValue(C->getInteropVar()).getPointer(*this);
OMPBuilder.createOMPInteropDestroy(Builder, InteropvarPtr, Device,
NumDependences, DependenceList,
- Data.HasNowaitClause);
+ Data.getHasNowaitClause());
}
}
auto ItOMPUseClause = S.getClausesOfKind<OMPUseClause>();
@@ -7987,7 +7989,7 @@ void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) {
EmitLValue(C->getInteropVar()).getPointer(*this);
OMPBuilder.createOMPInteropUse(Builder, InteropvarPtr, Device,
NumDependences, DependenceList,
- Data.HasNowaitClause);
+ Data.getHasNowaitClause());
}
}
}
@@ -8560,22 +8562,22 @@ void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
OMPTaskDataTy Data;
// Check if taskloop must be emitted without taskgroup.
- Data.Nogroup = S.getSingleClause<OMPNogroupClause>();
+ Data.setNogroup(S.getSingleClause<OMPNogroupClause>());
// TODO: Check if we should emit tied or untied task.
- Data.Tied = true;
+ Data.setTied(true);
// Set scheduling for taskloop
if (const auto *Clause = S.getSingleClause<OMPGrainsizeClause>()) {
// grainsize clause
Data.Schedule.setInt(/*IntVal=*/false);
Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
- Data.HasModifier =
- (Clause->getModifier() == OMPC_GRAINSIZE_strict) ? true : false;
+ Data.setHasModifier(
+ (Clause->getModifier() == OMPC_GRAINSIZE_strict) ? true : false);
} else if (const auto *Clause = S.getSingleClause<OMPNumTasksClause>()) {
// num_tasks clause
Data.Schedule.setInt(/*IntVal=*/true);
Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
- Data.HasModifier =
- (Clause->getModifier() == OMPC_NUMTASKS_strict) ? true : false;
+ Data.setHasModifier(
+ (Clause->getModifier() == OMPC_NUMTASKS_strict) ? true : false);
}
auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
@@ -8690,7 +8692,7 @@ void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
CodeGen);
};
- if (Data.Nogroup) {
+ if (Data.getNogroup()) {
EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen, Data);
} else {
CGM.getOpenMPRuntime().emitTaskgroupRegion(
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 1aa3fb1928279..133019180ce7d 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -271,7 +271,7 @@ void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
bool IsUnprototyped) {
assert(!CurGD.getDecl() && "CurGD was already set!");
CurGD = GD;
- CurFuncIsThunk = true;
+ setCurFuncIsThunk(true);
// Build FunctionArgs.
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
@@ -424,7 +424,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType);
// Disable the final ARC autorelease.
- AutoreleaseResult = false;
+ setAutoreleaseResult(false);
FinishThunk();
}
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index 2edd0988c39a7..22c1ab6a9da5e 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -93,9 +93,9 @@ BackendConsumer::BackendConsumer(CompilerInstance &CI, BackendAction Action,
TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
AsmOutStream(std::move(OS)), FS(VFS), Action(Action),
Gen(CreateLLVMCodeGen(CI, InFile, C, CoverageInfo)),
- LinkModules(std::move(LinkModules)), DiagConsumer(Diags, CodeGenOpts) {
+ LinkModules(0, std::move(LinkModules)), DiagConsumer(Diags, CodeGenOpts) {
DiagConsumer.setCurLinkModule(CurLinkModule);
- TimerIsEnabled = CodeGenOpts.TimePasses;
+ setTimerIsEnabled(CodeGenOpts.TimePasses);
{
llvm::sys::SmartScopedLock<true> Lock(*TimePassesMutex);
llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses;
@@ -127,12 +127,12 @@ void BackendConsumer::Initialize(ASTContext &Ctx) {
Context = &Ctx;
DiagConsumer.setSourceManager(&Ctx.getSourceManager());
- if (TimerIsEnabled)
+ if (getTimerIsEnabled())
LLVMIRGeneration.startTimer();
Gen->Initialize(Ctx);
- if (TimerIsEnabled)
+ if (getTimerIsEnabled())
LLVMIRGeneration.stopTimer();
}
@@ -142,12 +142,12 @@ bool BackendConsumer::HandleTopLevelDecl(DeclGroupRef D) {
"LLVM IR generation of declaration");
// Recurse.
- if (TimerIsEnabled && !LLVMIRGenerationRefCount++)
+ if (getTimerIsEnabled() && !LLVMIRGenerationRefCount++)
CI.getFrontendTimer().yieldTo(LLVMIRGeneration);
Gen->HandleTopLevelDecl(D);
- if (TimerIsEnabled && !--LLVMIRGenerationRefCount)
+ if (getTimerIsEnabled() && !--LLVMIRGenerationRefCount)
LLVMIRGeneration.yieldTo(CI.getFrontendTimer());
return true;
@@ -157,12 +157,12 @@ void BackendConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) {
PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
Context->getSourceManager(),
"LLVM IR generation of inline function");
- if (TimerIsEnabled)
+ if (getTimerIsEnabled())
CI.getFrontendTimer().yieldTo(LLVMIRGeneration);
Gen->HandleInlineFunctionDefinition(D);
- if (TimerIsEnabled)
+ if (getTimerIsEnabled())
LLVMIRGeneration.yieldTo(CI.getFrontendTimer());
}
@@ -172,20 +172,24 @@ void BackendConsumer::HandleInterestingDecl(DeclGroupRef D) {
// Links each entry in LinkModules into our module. Returns true on error.
bool BackendConsumer::LinkInModules(llvm::Module *M) {
- return linkInModules(*M, LinkModules, CodeGenOpts, LangOpts, TargetOpts,
- DiagConsumer);
+ SmallVector<LinkModule, 4> Modules;
+ Modules = std::move(LinkModules);
+ bool Failed = linkInModules(*M, Modules, CodeGenOpts, LangOpts, TargetOpts,
+ DiagConsumer);
+ LinkModules.assign(std::move(Modules));
+ return Failed;
}
void BackendConsumer::HandleTranslationUnit(ASTContext &C) {
{
llvm::TimeTraceScope TimeScope("Frontend");
PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
- if (TimerIsEnabled && !LLVMIRGenerationRefCount++)
+ if (getTimerIsEnabled() && !LLVMIRGenerationRefCount++)
CI.getFrontendTimer().yieldTo(LLVMIRGeneration);
Gen->HandleTranslationUnit(C);
- if (TimerIsEnabled && !--LLVMIRGenerationRefCount)
+ if (getTimerIsEnabled() && !--LLVMIRGenerationRefCount)
LLVMIRGeneration.yieldTo(CI.getFrontendTimer());
}
@@ -298,12 +302,13 @@ BackendConsumer::createDiagnosticHandler() {
}
CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext)
- : Act(_Act), VMContext(_VMContext ? _VMContext : new LLVMContext),
- OwnsVMContext(!_VMContext) {}
+ : Act(_Act), LinkModules(decltype(this->LinkModules)::withFlags(
+ unsigned(bool(!_VMContext)))),
+ VMContext(_VMContext ? _VMContext : new LLVMContext) {}
CodeGenAction::~CodeGenAction() {
TheModule.reset();
- if (OwnsVMContext)
+ if (getOwnsVMContext())
delete VMContext;
}
@@ -325,7 +330,7 @@ std::unique_ptr<llvm::Module> CodeGenAction::takeModule() {
}
llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
- OwnsVMContext = false;
+ setOwnsVMContext(false);
return VMContext;
}
@@ -371,7 +376,12 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
return nullptr;
// Load bitcode modules to link with, if we need to.
- if (clang::loadLinkModules(CI, *VMContext, LinkModules))
+ SmallVector<LinkModule, 4> ModulesToLink;
+ ModulesToLink = std::move(LinkModules);
+ bool FailedToLoadModules =
+ clang::loadLinkModules(CI, *VMContext, ModulesToLink);
+ LinkModules.assign(std::move(ModulesToLink));
+ if (FailedToLoadModules)
return nullptr;
CoverageSourceInfo *CoverageInfo = nullptr;
@@ -380,9 +390,10 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
CoverageInfo = CodeGen::CoverageMappingModuleGen::setUpCoverageCallbacks(
CI.getPreprocessor());
- std::unique_ptr<BackendConsumer> Result(new BackendConsumer(
- CI, BA, CI.getVirtualFileSystemPtr(), *VMContext, std::move(LinkModules),
- InFile, std::move(OS), CoverageInfo));
+ std::unique_ptr<BackendConsumer> Result(
+ new BackendConsumer(CI, BA, CI.getVirtualFileSystemPtr(), *VMContext,
+ SmallVector<LinkModule, 4>(std::move(LinkModules)),
+ InFile, std::move(OS), CoverageInfo));
BEConsumer = Result.get();
// Enable generating macro debug info only when debug info is not disabled and
@@ -449,7 +460,12 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) {
}
// Load bitcode modules to link with, if we need to.
- if (clang::loadLinkModules(CI, *VMContext, LinkModules))
+ SmallVector<LinkModule, 4> ModulesToLink;
+ ModulesToLink = std::move(LinkModules);
+ bool FailedToLoadModules =
+ clang::loadLinkModules(CI, *VMContext, ModulesToLink);
+ LinkModules.assign(std::move(ModulesToLink));
+ if (FailedToLoadModules)
return nullptr;
// Handle textual IR and bitcode file with one single module.
@@ -579,8 +595,8 @@ void CodeGenAction::ExecuteAction() {
// Set clang diagnostic handler. To do this we need to create a fake
// BackendConsumer.
BackendConsumer Result(CI, BA, CI.getVirtualFileSystemPtr(), *VMContext,
- std::move(LinkModules), "", nullptr, nullptr,
- TheModule.get());
+ SmallVector<LinkModule, 4>(std::move(LinkModules)), "",
+ nullptr, nullptr, TheModule.get());
// Link in each pending link module.
if (!CodeGenOpts.LinkBitcodePostopt && Result.LinkInModules(&*TheModule))
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index e5bca359e6a85..c0b08a2691380 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -63,11 +63,13 @@ using namespace CodeGen;
CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
: CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
Builder(cgm, cgm.getModule().getContext(), CGBuilderInserterTy(this)),
+ OMPLoopNestStack(decltype(this->OMPLoopNestStack)::withFlags(
+ (unsigned(bool(CodeGenUtils::shouldEmitLifetimeMarkers(
+ CGM.getCodeGenOpts(), CGM.getLangOpts())))
+ << 1))),
SanOpts(CGM.getLangOpts().Sanitize), CurFPFeatures(CGM.getLangOpts()),
DebugInfo(CGM.getModuleDebugInfo()),
- PGO(std::make_unique<CodeGenPGO>(cgm)),
- ShouldEmitLifetimeMarkers(CodeGenUtils::shouldEmitLifetimeMarkers(
- CGM.getCodeGenOpts(), CGM.getLangOpts())) {
+ PGO(std::make_unique<CodeGenPGO>(cgm)) {
if (!suppressNewContext)
CGM.getCXXABI().getMangleContext().startNewFunction();
EHStack.setCGF(this);
@@ -750,7 +752,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
const Decl *D = GD.getDecl();
- DidCallStackSave = false;
+ setDidCallStackSave(false);
CurCodeDecl = D;
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
if (FD && FD->usesSEHTry())
@@ -1170,7 +1172,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// convention.
DI->emitFunctionStart(GD, Loc, StartLoc,
DI->getFunctionType(FD, RetTy, Args), CurFn,
- CurFuncIsThunk);
+ getCurFuncIsThunk());
}
if (ShouldInstrumentFunction()) {
@@ -1280,7 +1282,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (getLangOpts().ObjCAutoRefCount &&
!CurFnInfo->isReturnsRetained() &&
RetTy->isObjCRetainableType())
- AutoreleaseResult = true;
+ setAutoreleaseResult(true);
}
EmitStartEHSpec(CurCodeDecl);
@@ -1570,11 +1572,11 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
if (Body) {
// Coroutines always emit lifetime markers.
if (isa<CoroutineBodyStmt>(Body))
- ShouldEmitLifetimeMarkers = true;
+ setShouldEmitLifetimeMarkers(true);
// Detect jumps that invalidate lifetime markers or bypass auto-var-init.
bool NeedsBypassDetection =
- ShouldEmitLifetimeMarkers ||
+ getShouldEmitLifetimeMarkers() ||
(CGM.getLangOpts().getTrivialAutoVarInit() !=
LangOptions::TrivialAutoVarInitKind::Uninitialized);
if (NeedsBypassDetection)
@@ -1659,8 +1661,9 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
// C11 6.9.1p12:
// If the '}' that terminates a function is reached, and the value of the
// function call is used by the caller, the behavior is undefined.
- if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() && !SawAsmBlock &&
- !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) {
+ if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() &&
+ !getSawAsmBlock() && !FD->getReturnType()->isVoidType() &&
+ Builder.GetInsertBlock()) {
bool ShouldEmitUnreachable =
CGM.getCodeGenOpts().StrictReturn ||
!CGM.MayDropFunctionReturn(FD->getASTContext(), FD->getReturnType());
@@ -2875,19 +2878,19 @@ CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
: CGF(CGF) {
- assert(!CGF->IsSanitizerScope);
- CGF->IsSanitizerScope = true;
+ assert(!CGF->getIsSanitizerScope());
+ CGF->setIsSanitizerScope(true);
}
CodeGenFunction::SanitizerScope::~SanitizerScope() {
- CGF->IsSanitizerScope = false;
+ CGF->setIsSanitizerScope(false);
}
void CodeGenFunction::InsertHelper(llvm::Instruction *I,
const llvm::Twine &Name,
llvm::BasicBlock::iterator InsertPt) const {
LoopStack.InsertHelper(I);
- if (IsSanitizerScope)
+ if (getIsSanitizerScope())
I->setNoSanitizeMetadata();
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 00294ad547d5e..3eb6d828e02ab 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -39,6 +39,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/ValueHandle.h"
@@ -327,10 +328,11 @@ class CodeGenFunction : public CodeGenTypeCache {
/// loop nest goes out of scope) or a second loop in the same level in which
/// case it would be ambiguous into which of the two (or more) loops the loop
/// nest would extend.
- SmallVector<llvm::CanonicalLoopInfo *, 4> OMPLoopNestStack;
+ llvm::SmallVectorWithFlags<llvm::CanonicalLoopInfo *, 4, 2> OMPLoopNestStack;
/// Stack to track the controlled convergence tokens.
- SmallVector<llvm::ConvergenceControlInst *, 4> ConvergenceTokenStack;
+ llvm::SmallVectorWithFlags<llvm::ConvergenceControlInst *, 4, 4>
+ ConvergenceTokenStack;
/// Number of nested loop to be consumed by the last surrounding
/// loop-associated directive.
@@ -374,7 +376,7 @@ class CodeGenFunction : public CodeGenTypeCache {
const CastExpr *CurCast = nullptr;
/// Save Parameter Decl for coroutine.
- llvm::SmallVector<const ParmVarDecl *, 4> FnArgs;
+ llvm::SmallVectorWithFlags<const ParmVarDecl *, 4, 4> FnArgs;
// Holds coroutine data if the current function is a coroutine. We use a
// wrapper to manage its lifetime, so that we don't have to define CGCoroData
@@ -594,7 +596,8 @@ class CodeGenFunction : public CodeGenTypeCache {
SanitizerSet SanOpts;
/// True if CodeGen currently emits code implementing sanitizer checks.
- bool IsSanitizerScope = false;
+ bool getIsSanitizerScope() const { return FnArgs.getFlag(0); }
+ void setIsSanitizerScope(bool Value) { FnArgs.setFlag(0, Value); }
/// RAII object to set/unset CodeGenFunction::IsSanitizerScope.
class SanitizerScope {
@@ -607,24 +610,40 @@ class CodeGenFunction : public CodeGenTypeCache {
/// In C++, whether we are code generating a thunk. This controls whether we
/// should emit cleanups.
- bool CurFuncIsThunk = false;
+ bool getCurFuncIsThunk() const { return FnArgs.getFlag(1); }
+ void setCurFuncIsThunk(bool Value) { FnArgs.setFlag(1, Value); }
/// In ARC, whether we should autorelease the return value.
- bool AutoreleaseResult = false;
+ bool getAutoreleaseResult() const { return FnArgs.getFlag(2); }
+ bool setAutoreleaseResult(bool Value) {
+ FnArgs.setFlag(2, Value);
+ return Value;
+ }
/// Whether we processed a Microsoft-style asm block during CodeGen. These can
/// potentially set the return value.
- bool SawAsmBlock = false;
+ bool getSawAsmBlock() const { return FnArgs.getFlag(3); }
+ void setSawAsmBlock(bool Value) { FnArgs.setFlag(3, Value); }
GlobalDecl CurSEHParent;
/// True if the current function is an outlined SEH helper. This can be a
/// finally block or filter expression.
- bool IsOutlinedSEHHelper = false;
+ bool getIsOutlinedSEHHelper() const {
+ return ConvergenceTokenStack.getFlag(0);
+ }
+ void setIsOutlinedSEHHelper(bool Value) {
+ ConvergenceTokenStack.setFlag(0, Value);
+ }
/// True if CodeGen currently emits code inside presereved access index
/// region.
- bool IsInPreservedAIRegion = false;
+ bool getIsInPreservedAIRegion() const {
+ return ConvergenceTokenStack.getFlag(1);
+ }
+ void setIsInPreservedAIRegion(bool Value) {
+ ConvergenceTokenStack.setFlag(1, Value);
+ }
/// True if the current statement has nomerge attribute.
bool InNoMergeAttributedStmt = false;
@@ -810,7 +829,10 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::BasicBlock *OMPAfterScanBlock = nullptr;
llvm::BasicBlock *OMPScanExitBlock = nullptr;
llvm::BasicBlock *OMPScanDispatch = nullptr;
- bool OMPFirstScanLoop = false;
+ bool getOMPFirstScanLoop() const { return ConvergenceTokenStack.getFlag(2); }
+ void setOMPFirstScanLoop(bool Value) {
+ ConvergenceTokenStack.setFlag(2, Value);
+ }
/// Manages parent directive for scan directives.
class ParentLoopDirectiveForScanRegion {
@@ -1077,8 +1099,8 @@ class CodeGenFunction : public CodeGenTypeCache {
CleanupStackDepth = CGF.EHStack.stable_begin();
LifetimeExtendedCleanupStackSize =
CGF.LifetimeExtendedCleanupStack.size();
- OldDidCallStackSave = CGF.DidCallStackSave;
- CGF.DidCallStackSave = false;
+ OldDidCallStackSave = CGF.getDidCallStackSave();
+ CGF.setDidCallStackSave(false);
OldCleanupScopeDepth = CGF.CurrentCleanupScopeDepth;
CGF.CurrentCleanupScopeDepth = CleanupStackDepth;
}
@@ -1103,7 +1125,7 @@ class CodeGenFunction : public CodeGenTypeCache {
void
ForceCleanup(std::initializer_list<llvm::Value **> ValuesToReload = {}) {
assert(PerformCleanup && "Already forced cleanup");
- CGF.DidCallStackSave = OldDidCallStackSave;
+ CGF.setDidCallStackSave(OldDidCallStackSave);
DeactivateCleanups.ForceDeactivate();
CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize,
ValuesToReload);
@@ -1579,11 +1601,15 @@ class CodeGenFunction : public CodeGenTypeCache {
CGDebugInfo *DebugInfo;
/// Used to create unique names for artificial VLA size debug info variables.
unsigned VLAExprCounter = 0;
- bool DisableDebugInfo = false;
+ bool getDisableDebugInfo() const { return ConvergenceTokenStack.getFlag(3); }
+ void setDisableDebugInfo(bool Value) {
+ ConvergenceTokenStack.setFlag(3, Value);
+ }
/// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
/// calling llvm.stacksave for multiple VLAs in the same scope.
- bool DidCallStackSave = false;
+ bool getDidCallStackSave() const { return OMPLoopNestStack.getFlag(0); }
+ void setDidCallStackSave(bool Value) { OMPLoopNestStack.setFlag(0, Value); }
/// IndirectBranch - The first time an indirect goto is seen we create a block
/// with an indirect branch. Every time we see the address of a label taken,
@@ -2227,7 +2253,13 @@ class CodeGenFunction : public CodeGenTypeCache {
/// True if we need emit the life-time markers. This is initially set in
/// the constructor, but could be overwritten to true if this is a coroutine.
- bool ShouldEmitLifetimeMarkers;
+ bool getShouldEmitLifetimeMarkers() const {
+ return OMPLoopNestStack.getFlag(1);
+ }
+ bool setShouldEmitLifetimeMarkers(bool Value) {
+ OMPLoopNestStack.setFlag(1, Value);
+ return Value;
+ }
/// Add OpenCL kernel arg metadata and the kernel attribute metadata to
/// the function metadata.
@@ -2240,12 +2272,12 @@ class CodeGenFunction : public CodeGenTypeCache {
CodeGenTypes &getTypes() const { return CGM.getTypes(); }
ASTContext &getContext() const { return CGM.getContext(); }
CGDebugInfo *getDebugInfo() {
- if (DisableDebugInfo)
+ if (getDisableDebugInfo())
return nullptr;
return DebugInfo;
}
- void disableDebugInfo() { DisableDebugInfo = true; }
- void enableDebugInfo() { DisableDebugInfo = false; }
+ void disableDebugInfo() { setDisableDebugInfo(true); }
+ void enableDebugInfo() { setDisableDebugInfo(false); }
bool shouldUseFusedARCCalls() {
return CGM.getCodeGenOpts().OptimizationLevel == 0;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 00a82819681c1..b4b22819f4959 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -599,9 +599,9 @@ CodeGenModule::CodeGenModule(ASTContext &C,
// Build C++20 Module initializers.
// TODO: Add Microsoft here once we know the mangling required for the
// initializers.
- CXX20ModuleInits =
- LangOpts.CPlusPlusModules && getCXXABI().getMangleContext().getKind() ==
- ItaniumMangleContext::MK_Itanium;
+ setCXX20ModuleInits(LangOpts.CPlusPlusModules &&
+ getCXXABI().getMangleContext().getKind() ==
+ ItaniumMangleContext::MK_Itanium);
RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC();
@@ -1184,7 +1184,7 @@ CodeGenModule::StackProtectorAttribute(const Decl *D) const {
void CodeGenModule::Release() {
Module *Primary = getContext().getCurrentNamedModule();
- if (CXX20ModuleInits && Primary && !Primary->isHeaderLikeModule())
+ if (getCXX20ModuleInits() && Primary && !Primary->isHeaderLikeModule())
EmitModuleInitializers(Primary);
EmitDeferred();
DeferredDecls.insert_range(EmittedDeferredDecls);
@@ -1205,7 +1205,7 @@ void CodeGenModule::Release() {
// Module implementations are initialized the same way as a regular TU that
// imports one or more modules.
- if (CXX20ModuleInits && Primary && Primary->isInterfaceOrPartition())
+ if (getCXX20ModuleInits() && Primary && Primary->isInterfaceOrPartition())
EmitCXXModuleInitFunc(Primary);
else
EmitCXXGlobalInitFunc();
@@ -4062,7 +4062,7 @@ static void addLinkOptionsPostorder(CodeGenModule &CGM, Module *Mod,
// For modules that use export_as for linking, use that module
// name instead.
- if (Mod->UseExportAsModuleLinkName)
+ if (Mod->getUseExportAsModuleLinkName())
return;
for (const Module::LinkLibrary &LL : llvm::reverse(Mod->LinkLibraries)) {
@@ -4155,7 +4155,7 @@ void CodeGenModule::EmitModuleLinkOptions() {
for (const auto &SM : Mod->submodules()) {
// Skip explicit children; they need to be explicitly imported to be
// linked against.
- if (SM->IsExplicit)
+ if (SM->getIsExplicit())
continue;
if (Visited.insert(SM).second) {
@@ -4613,7 +4613,7 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
// A definition of an inline constexpr static data member may change
// linkage later if it's redeclared outside the class.
return false;
- if (CXX20ModuleInits && VD->getOwningModule() &&
+ if (getCXX20ModuleInits() && VD->getOwningModule() &&
!VD->getOwningModule()->isModuleMapModule()) {
// For CXX20, module-owned initializers need to be deferred, since it is
// not known at this point if they will be run for the current module or
@@ -8225,7 +8225,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// For C++ standard modules we are done - we will call the module
// initializer for imported modules, and that will likewise call those for
// any imports it has.
- if (CXX20ModuleInits && Import->getImportedModule() &&
+ if (getCXX20ModuleInits() && Import->getImportedModule() &&
Import->getImportedModule()->isNamedModule())
break;
@@ -8250,7 +8250,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
for (Module *Submodule : Mod->submodules()) {
// Skip explicit children; they need to be explicitly imported to emit
// the initializers.
- if (Submodule->IsExplicit)
+ if (Submodule->getIsExplicit())
continue;
if (Visited.insert(Submodule).second)
@@ -9040,7 +9040,7 @@ void CodeGenModule::addPendingGlobalDelete(
PendingMSVCGlobalDeletes.insert({GlobalDeleteAlias, OperatorDeleteFD});
}
-void CodeGenModule::noteDirectGlobalDelete() { HasDirectGlobalDelete = true; }
+void CodeGenModule::noteDirectGlobalDelete() { setHasDirectGlobalDelete(true); }
/// Get or create the MSVC-compatible __global_delete wrapper function.
///
@@ -9156,7 +9156,7 @@ void CodeGenModule::emitGlobalDeleteForwardingBodies() {
// path), we know ::operator delete must exist, so we replace the wrapper's
// weak alias-to-empty fallback with a real __global_delete definition that
// forwards to it.
- if (!HasDirectGlobalDelete)
+ if (!getHasDirectGlobalDelete())
return;
for (const auto &Entry : PendingMSVCGlobalDeletes) {
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index d9f3901c0c67e..4e93aa0296e18 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -35,6 +35,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
@@ -365,7 +366,10 @@ class CodeGenModule : public CodeGenTypeCache {
std::unique_ptr<CGCXXABI> ABI;
llvm::LLVMContext &VMContext;
std::string ModuleNameHash;
- bool CXX20ModuleInits = false;
+ bool getCXX20ModuleInits() const { return ELFDependentLibraries.getFlag(0); }
+ void setCXX20ModuleInits(bool Value) {
+ ELFDependentLibraries.setFlag(0, Value);
+ }
std::unique_ptr<CodeGenTBAA> TBAA;
mutable std::unique_ptr<TargetCodeGenInfo> TheTargetCodeGenInfo;
@@ -569,7 +573,12 @@ class CodeGenModule : public CodeGenTypeCache {
/// Whether this TU contains a direct use of global ::operator delete
/// (indicating that __global_delete forwarding bodies should be emitted).
- bool HasDirectGlobalDelete = false;
+ bool getHasDirectGlobalDelete() const {
+ return ELFDependentLibraries.getFlag(1);
+ }
+ void setHasDirectGlobalDelete(bool Value) {
+ ELFDependentLibraries.setFlag(1, Value);
+ }
typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *>
GlobalInitData;
@@ -627,7 +636,7 @@ class CodeGenModule : public CodeGenTypeCache {
SmallVector<llvm::MDNode *, 16> LinkerOptionsMetadata;
/// A vector of metadata strings for dependent libraries for ELF.
- SmallVector<llvm::MDNode *, 16> ELFDependentLibraries;
+ llvm::SmallVectorWithFlags<llvm::MDNode *, 16, 2> ELFDependentLibraries;
/// Global variable for copyright pragma comment (if present).
llvm::GlobalVariable *LoadTimeCommentGlobal = nullptr;
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 1b16be8106f56..c858c81f8a211 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/DiagnosticFrontend.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/Support/CommandLine.h"
@@ -489,7 +490,10 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
/// A flag that is set when the current count should be recorded on the
/// next statement, such as at the exit of a loop.
- bool RecordNextStmtCount;
+ bool getRecordNextStmtCount() const { return BreakContinueStack.getFlag(0); }
+ void setRecordNextStmtCount(bool Value) {
+ BreakContinueStack.setFlag(0, Value);
+ }
/// The count at the current location in the traversal.
uint64_t CurrentCount;
@@ -503,16 +507,16 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
uint64_t ContinueCount = 0;
BreakContinue() = default;
};
- SmallVector<BreakContinue, 8> BreakContinueStack;
+ llvm::SmallVectorWithFlags<BreakContinue, 8> BreakContinueStack;
ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
CodeGenPGO &PGO)
- : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
+ : PGO(PGO), CountMap(CountMap) {}
void RecordStmtCount(const Stmt *S) {
- if (RecordNextStmtCount) {
+ if (getRecordNextStmtCount()) {
CountMap[S] = CurrentCount;
- RecordNextStmtCount = false;
+ setRecordNextStmtCount(false);
}
}
@@ -567,7 +571,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
if (S->getRetValue())
Visit(S->getRetValue());
CurrentCount = 0;
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitCXXThrowExpr(const CXXThrowExpr *E) {
@@ -575,17 +579,17 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
if (E->getSubExpr())
Visit(E->getSubExpr());
CurrentCount = 0;
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitGotoStmt(const GotoStmt *S) {
RecordStmtCount(S);
CurrentCount = 0;
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitLabelStmt(const LabelStmt *S) {
- RecordNextStmtCount = false;
+ setRecordNextStmtCount(false);
// Counter tracks the block following the label.
uint64_t BlockCount = setCount(PGO.getRegionCount(S));
CountMap[S] = BlockCount;
@@ -597,7 +601,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
BreakContinueStack.back().BreakCount += CurrentCount;
CurrentCount = 0;
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitContinueStmt(const ContinueStmt *S) {
@@ -605,7 +609,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
BreakContinueStack.back().ContinueCount += CurrentCount;
CurrentCount = 0;
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitWhileStmt(const WhileStmt *S) {
@@ -630,7 +634,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
CountMap[S->getCond()] = CondCount;
Visit(S->getCond());
setCount(BC.BreakCount + CondCount - BodyCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitDoStmt(const DoStmt *S) {
@@ -651,7 +655,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
CountMap[S->getCond()] = CondCount;
Visit(S->getCond());
setCount(BC.BreakCount + CondCount - LoopCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitForStmt(const ForStmt *S) {
@@ -686,7 +690,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
Visit(S->getCond());
}
setCount(BC.BreakCount + CondCount - BodyCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
@@ -720,7 +724,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
CountMap[S->getCond()] = CondCount;
Visit(S->getCond());
setCount(BC.BreakCount + CondCount - BodyCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
@@ -737,7 +741,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
BodyCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitSwitchStmt(const SwitchStmt *S) {
@@ -754,11 +758,11 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
BreakContinueStack.back().ContinueCount += BC.ContinueCount;
// Counter tracks the exit block of the switch.
setCount(PGO.getRegionCount(S));
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitSwitchCase(const SwitchCase *S) {
- RecordNextStmtCount = false;
+ setRecordNextStmtCount(false);
// Counter for this particular case. This counts only jumps from the
// switch header and does not include fallthrough from the case before
// this one.
@@ -767,7 +771,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
// We need the count without fallthrough in the mapping, so it's more useful
// for branch probabilities.
CountMap[S] = CaseCount;
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
Visit(S->getSubStmt());
}
@@ -802,7 +806,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
} else
OutCount += ElseCount;
setCount(OutCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitCXXTryStmt(const CXXTryStmt *S) {
@@ -812,11 +816,11 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
Visit(S->getHandler(I));
// Counter tracks the continuation block of the try statement.
setCount(PGO.getRegionCount(S));
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitCXXCatchStmt(const CXXCatchStmt *S) {
- RecordNextStmtCount = false;
+ setRecordNextStmtCount(false);
// Counter tracks the catch statement's handler block.
uint64_t CatchCount = setCount(PGO.getRegionCount(S));
CountMap[S] = CatchCount;
@@ -841,7 +845,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
OutCount += CurrentCount;
setCount(OutCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitBinLAnd(const BinaryOperator *E) {
@@ -853,7 +857,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
CountMap[E->getRHS()] = RHSCount;
Visit(E->getRHS());
setCount(ParentCount + RHSCount - CurrentCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
void VisitBinLOr(const BinaryOperator *E) {
@@ -865,7 +869,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
CountMap[E->getRHS()] = RHSCount;
Visit(E->getRHS());
setCount(ParentCount + RHSCount - CurrentCount);
- RecordNextStmtCount = true;
+ setRecordNextStmtCount(true);
}
};
} // end anonymous namespace
diff --git a/clang/lib/CodeGen/ConstantEmitter.h b/clang/lib/CodeGen/ConstantEmitter.h
index 581b05ae87add..5c326ff51d65b 100644
--- a/clang/lib/CodeGen/ConstantEmitter.h
+++ b/clang/lib/CodeGen/ConstantEmitter.h
@@ -16,6 +16,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
namespace CodeGen {
@@ -37,15 +38,13 @@ class ConstantEmitter {
/// Whether the constant-emission failed.
bool Failed = false;
- /// Whether we're in a constant context.
- bool InConstantContext = false;
-
/// The AST address space where this (non-abstract) initializer is going.
/// Used for generating appropriate placeholders.
LangAS DestAddressSpace = LangAS::Default;
- llvm::SmallVector<std::pair<llvm::Constant *, llvm::GlobalVariable*>, 4>
- PlaceholderAddresses;
+ llvm::SmallVectorWithFlags<
+ std::pair<llvm::Constant *, llvm::GlobalVariable *>, 4>
+ PlaceholderAddresses;
public:
ConstantEmitter(CodeGenModule &CGM, CodeGenFunction *CGF = nullptr)
@@ -67,8 +66,9 @@ class ConstantEmitter {
return Abstract;
}
- bool isInConstantContext() const { return InConstantContext; }
- void setInConstantContext(bool var) { InConstantContext = var; }
+ /// Whether we're in a constant context.
+ bool isInConstantContext() const { return PlaceholderAddresses.getFlag(0); }
+ void setInConstantContext(bool var) { PlaceholderAddresses.setFlag(0, var); }
/// Try to emit the initiaizer of the given declaration as an abstract
/// constant. If this succeeds, the emission must be finalized.
diff --git a/clang/lib/CodeGen/ConstantInitBuilder.cpp b/clang/lib/CodeGen/ConstantInitBuilder.cpp
index 93e5d40a11fe7..e026c72774581 100644
--- a/clang/lib/CodeGen/ConstantInitBuilder.cpp
+++ b/clang/lib/CodeGen/ConstantInitBuilder.cpp
@@ -58,7 +58,7 @@ ConstantInitBuilderBase::createFuture(llvm::Constant *initializer) {
// Only used in this file.
inline ConstantInitFuture::ConstantInitFuture(ConstantInitBuilderBase *builder)
: Data(builder) {
- assert(!builder->Frozen);
+ assert(!builder->getFrozen());
assert(builder->Buffer.size() == 1);
assert(builder->Buffer[0] != nullptr);
}
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 5bbb742a7b1ef..9e15fea510f7b 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -32,6 +32,7 @@
#include "clang/Basic/PointerAuthOptions.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "clang/CodeGenUtils/ItaniumCXXABIUtils.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Instructions.h"
@@ -51,25 +52,29 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
/// All the thread wrapper functions that have been used.
- llvm::SmallVector<std::pair<const VarDecl *, llvm::Function *>, 8>
+ llvm::SmallVectorWithFlags<std::pair<const VarDecl *, llvm::Function *>, 8, 3>
ThreadWrappers;
protected:
- bool UseARMMethodPtrABI;
- bool UseARMGuardVarABI;
- bool Use32BitVTableOffsetABI;
+ bool getUseARMMethodPtrABI() const { return ThreadWrappers.getFlag(0); }
+ void setUseARMMethodPtrABI(bool Value) { ThreadWrappers.setFlag(0, Value); }
+ bool getUseARMGuardVarABI() const { return ThreadWrappers.getFlag(1); }
+ void setUseARMGuardVarABI(bool Value) { ThreadWrappers.setFlag(1, Value); }
+ bool getUse32BitVTableOffsetABI() const { return ThreadWrappers.getFlag(2); }
+ void setUse32BitVTableOffsetABI(bool Value) {
+ ThreadWrappers.setFlag(2, Value);
+ }
ItaniumMangleContext &getMangleContext() {
return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext());
}
public:
- ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
- bool UseARMMethodPtrABI = false,
- bool UseARMGuardVarABI = false) :
- CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
- UseARMGuardVarABI(UseARMGuardVarABI),
- Use32BitVTableOffsetABI(false) { }
+ ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool UseARMMethodPtrABI = false,
+ bool UseARMGuardVarABI = false)
+ : CGCXXABI(CGM), ThreadWrappers(decltype(ThreadWrappers)::withFlags(
+ unsigned(UseARMMethodPtrABI) |
+ (unsigned(UseARMGuardVarABI) << 1))) {}
bool classifyReturnType(CGFunctionInfo &FI) const override;
@@ -525,7 +530,7 @@ class ARMCXXABI : public ItaniumCXXABI {
class AppleARM64CXXABI : public ARMCXXABI {
public:
AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {
- Use32BitVTableOffsetABI = true;
+ setUse32BitVTableOffsetABI(true);
}
// ARM64 libraries are prepared for non-unique RTTI.
@@ -661,7 +666,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// Compute the true adjustment.
llvm::Value *Adj = RawAdj;
- if (UseARMMethodPtrABI)
+ if (getUseARMMethodPtrABI())
Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
// Apply the adjustment and cast back to the original struct type
@@ -676,7 +681,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// If the LSB in the function pointer is 1, the function pointer points to
// a virtual function.
llvm::Value *IsVirtual;
- if (UseARMMethodPtrABI)
+ if (getUseARMMethodPtrABI())
IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
else
IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
@@ -700,9 +705,9 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// On ARM64, to reserve extra space in virtual member function pointers,
// we only pay attention to the low 32 bits of the offset.
llvm::Value *VTableOffset = FnAsInt;
- if (!UseARMMethodPtrABI)
+ if (!getUseARMMethodPtrABI())
VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
- if (Use32BitVTableOffsetABI) {
+ if (getUse32BitVTableOffsetABI()) {
VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.Int32Ty);
VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
}
@@ -983,7 +988,7 @@ ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
llvm::BasicBlock *MergeBB = CGF.createBasicBlock("merge");
// Check whether we have a virtual offset or a pointer to a function.
- assert(UseARMMethodPtrABI && "ARM ABI expected");
+ assert(getUseARMMethodPtrABI() && "ARM ABI expected");
llvm::Value *Adj = Builder.CreateExtractValue(src, 1, "memptr.adj");
llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
@@ -1036,7 +1041,7 @@ ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
}
// The this-adjustment is left-shifted by 1 on ARM.
- if (UseARMMethodPtrABI) {
+ if (getUseARMMethodPtrABI()) {
uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
offset <<= 1;
adj = llvm::ConstantInt::get(adj->getType(), offset);
@@ -1118,7 +1123,7 @@ ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
}
// The this-adjustment is left-shifted by 1 on ARM.
- if (UseARMMethodPtrABI) {
+ if (getUseARMMethodPtrABI()) {
uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
offset <<= 1;
adj = llvm::ConstantInt::get(adj->getType(), offset);
@@ -1183,7 +1188,7 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,
VTableOffset = Index * PointerWidth.getQuantity();
}
- if (UseARMMethodPtrABI) {
+ if (getUseARMMethodPtrABI()) {
// ARM C++ ABI 3.2.1:
// This ABI specifies that adj contains twice the this
// adjustment, plus 1 if the member function is virtual. The
@@ -1241,8 +1246,8 @@ llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,
MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
- (UseARMMethodPtrABI ? 2 : 1) *
- ThisAdjustment.getQuantity());
+ (getUseARMMethodPtrABI() ? 2 : 1) *
+ ThisAdjustment.getQuantity());
}
return llvm::ConstantStruct::getAnon(MemPtr);
@@ -1330,7 +1335,7 @@ ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
// Null member function pointers on ARM clear the low bit of Adj,
// so the zero condition has to check that neither low bit is set.
- if (UseARMMethodPtrABI) {
+ if (getUseARMMethodPtrABI()) {
llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
// Compute (l.adj | r.adj) & 1 and test it against zero.
@@ -1370,7 +1375,7 @@ ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
// On ARM, a member function pointer is also non-null if the low bit of 'adj'
// (the virtual bit) is set.
- if (UseARMMethodPtrABI) {
+ if (getUseARMMethodPtrABI()) {
llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
@@ -2711,7 +2716,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
} else {
// Guard variables are 64 bits in the generic ABI and size width on ARM
// (i.e. 32-bit on AArch32, 64-bit on AArch64).
- if (UseARMGuardVarABI) {
+ if (getUseARMGuardVarABI()) {
guardTy = CGF.SizeTy;
guardAlignment = CGF.getSizeAlign();
} else {
@@ -2824,7 +2829,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
// variable; all other bits are platform defined. Bit 0 shall be 0 when the
// variable is not initialized and 1 when it is.
llvm::Value *V =
- (UseARMGuardVarABI && !useInt8GuardVariable)
+ (getUseARMGuardVarABI() && !useInt8GuardVariable)
? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
: LI;
llvm::Value *NeedsInit = Builder.CreateIsNull(V, "guard.uninitialized");
@@ -3458,7 +3463,7 @@ ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(const CXXMethodDecl *MD) {
// Start codegen.
CodeGenFunction CGF(CGM);
CGF.CurGD = GlobalDecl(MD);
- CGF.CurFuncIsThunk = true;
+ CGF.setCurFuncIsThunk(true);
// Build FunctionArgs.
FunctionArgList FunctionArgs;
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 86916104d1344..ad43601148f9c 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1623,7 +1623,7 @@ void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
// without making our codegen depend on debug info settings.
llvm::Value *This = loadIncomingCXXThis(CGF);
const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
- if (!CGF.CurFuncIsThunk && MD->isVirtual()) {
+ if (!CGF.getCurFuncIsThunk() && MD->isVirtual()) {
CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.CurGD);
if (!Adjustment.isZero()) {
assert(Adjustment.isPositive());
@@ -2156,7 +2156,7 @@ MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
// Start codegen.
CodeGenFunction CGF(CGM);
CGF.CurGD = GlobalDecl(MD);
- CGF.CurFuncIsThunk = true;
+ CGF.setCurFuncIsThunk(true);
// Build FunctionArgs, but only include the implicit 'this' parameter
// declaration.
diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
index 88ab809e78a8e..623b4b58a5b8b 100644
--- a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
+++ b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
@@ -278,7 +278,7 @@ class PCHContainerGenerator : public ASTConsumer {
llvm::report_fatal_error(llvm::Twine(Error));
// Emit the serialized Clang AST into its own section.
- assert(Buffer->IsComplete && "serialization did not complete");
+ assert(Buffer->getIsComplete() && "serialization did not complete");
auto &SerializedAST = Buffer->Data;
auto Size = SerializedAST.size();
@@ -333,7 +333,7 @@ class PCHContainerGenerator : public ASTConsumer {
// Free the memory for the temporary buffer.
llvm::SmallVector<char, 0> Empty;
- SerializedAST = std::move(Empty);
+ SerializedAST.assign(std::move(Empty));
}
};
diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp
index 9b9a44270b8e6..4a0772c09038b 100644
--- a/clang/lib/CodeGen/SwiftCallingConv.cpp
+++ b/clang/lib/CodeGen/SwiftCallingConv.cpp
@@ -468,7 +468,7 @@ bool SwiftAggLowering::shouldMergeEntries(const StorageEntry &first,
void SwiftAggLowering::finish() {
if (Entries.empty()) {
- Finished = true;
+ setFinished(true);
return;
}
@@ -495,12 +495,12 @@ void SwiftAggLowering::finish() {
// The rest of the algorithm leaves non-opaque entries alone, so if we
// have no opaque entries, we're done.
if (!hasOpaqueEntries) {
- Finished = true;
+ setFinished(true);
return;
}
// Okay, move the entries to a temporary and rebuild Entries.
- auto orig = std::move(Entries);
+ auto orig = SmallVector<StorageEntry, 4>(std::move(Entries));
assert(Entries.empty());
for (size_t i = 0, e = orig.size(); i != e; ++i) {
@@ -554,11 +554,11 @@ void SwiftAggLowering::finish() {
}
// Okay, finally finished.
- Finished = true;
+ setFinished(true);
}
void SwiftAggLowering::enumerateComponents(EnumerationCallback callback) const {
- assert(Finished && "haven't yet finished lowering");
+ assert(getFinished() && "haven't yet finished lowering");
for (auto &entry : Entries) {
callback(entry.Begin, entry.End, entry.Type);
@@ -567,7 +567,7 @@ void SwiftAggLowering::enumerateComponents(EnumerationCallback callback) const {
std::pair<llvm::StructType*, llvm::Type*>
SwiftAggLowering::getCoerceAndExpandTypes() const {
- assert(Finished && "haven't yet finished lowering");
+ assert(getFinished() && "haven't yet finished lowering");
auto &ctx = CGM.getLLVMContext();
@@ -624,7 +624,7 @@ SwiftAggLowering::getCoerceAndExpandTypes() const {
}
bool SwiftAggLowering::shouldPassIndirectly(bool asReturnValue) const {
- assert(Finished && "haven't yet finished lowering");
+ assert(getFinished() && "haven't yet finished lowering");
// Empty types don't need to be passed indirectly.
if (Entries.empty()) return false;
diff --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
index 4a7bdba6d917e..7a04a52251b5f 100644
--- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp
@@ -7315,11 +7315,11 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID,
}
// Enable underlying preserve_*_access_index() generation.
- bool OldIsInPreservedAIRegion = IsInPreservedAIRegion;
- IsInPreservedAIRegion = true;
+ bool OldIsInPreservedAIRegion = getIsInPreservedAIRegion();
+ setIsInPreservedAIRegion(true);
Value *FieldAddr = IsBitField ? EmitLValue(Arg).getRawBitFieldPointer(*this)
: EmitLValue(Arg).emitRawPointer(*this);
- IsInPreservedAIRegion = OldIsInPreservedAIRegion;
+ setIsInPreservedAIRegion(OldIsInPreservedAIRegion);
ConstantInt *C = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
Value *InfoKind = ConstantInt::get(Int64Ty, C->getSExtValue());
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp
index fcd2086964c48..98722973cc705 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -8,6 +8,7 @@
#include "ABIInfoImpl.h"
#include "TargetInfo.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <algorithm>
using namespace clang;
@@ -225,14 +226,18 @@ class SparcV9ABIInfo : public ABIInfo {
struct CoerceBuilder {
llvm::LLVMContext &Context;
const llvm::DataLayout &DL;
- SmallVector<llvm::Type*, 8> Elems;
+ llvm::SmallVectorWithFlags<llvm::Type *, 8, 2> Elems;
uint64_t Size;
- bool InReg;
- bool IsVarArg;
+ bool getInReg() const { return Elems.getFlag(0); }
+ void setInReg(bool Value) { Elems.setFlag(0, Value); }
+ bool getIsVarArg() const { return Elems.getFlag(1); }
+ void setIsVarArg(bool Value) { Elems.setFlag(1, Value); }
CoerceBuilder(llvm::LLVMContext &c, const llvm::DataLayout &dl,
bool IsVarArg)
- : Context(c), DL(dl), Size(0), InReg(false), IsVarArg(IsVarArg) {}
+ : Context(c), DL(dl),
+ Elems(decltype(Elems)::withFlags((unsigned(IsVarArg) << 1))),
+ Size(0) {}
// Pad Elems with integers until Size is ToSize.
void pad(uint64_t ToSize) {
@@ -263,14 +268,14 @@ class SparcV9ABIInfo : public ABIInfo {
// Add a floating point element at Offset.
void addFloat(uint64_t Offset, llvm::Type *Ty, unsigned Bits) {
// Varargs are treated as integers.
- if (IsVarArg)
+ if (getIsVarArg())
return;
// Unaligned floats are treated as integers.
if (Offset % Bits)
return;
// The InReg flag is only required if there are any floats < 64 bits.
if (Bits < 64)
- InReg = true;
+ setInReg(true);
pad(Offset);
Elems.push_back(Ty);
Size = Offset + Bits;
@@ -431,7 +436,7 @@ ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit,
llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
ABIArgInfo AAI = ABIArgInfo::getDirect(CoerceTy, 0, Padding);
- AAI.setInReg(CB.InReg);
+ AAI.setInReg(CB.getInReg());
return AAI;
}
diff --git a/clang/lib/CodeGen/VarBypassDetector.cpp b/clang/lib/CodeGen/VarBypassDetector.cpp
index f19ac2de6ea45..24a6f548523fd 100644
--- a/clang/lib/CodeGen/VarBypassDetector.cpp
+++ b/clang/lib/CodeGen/VarBypassDetector.cpp
@@ -48,12 +48,12 @@ void VarBypassDetector::Init(CodeGenModule &CGM, const Stmt *Body) {
Bypasses.clear();
BypassedVarsAtSource.clear();
Scopes = {{~0U, nullptr}};
- AlwaysBypassed = false;
+ setAlwaysBypassed(false);
if (!hasJumpStmts(Body))
return;
unsigned ParentScope = 0;
- AlwaysBypassed = !BuildScopeInformation(CGM, Body, ParentScope);
- if (!AlwaysBypassed)
+ setAlwaysBypassed(!BuildScopeInformation(CGM, Body, ParentScope));
+ if (!isAlwaysBypassed())
Detect();
}
diff --git a/clang/lib/CodeGen/VarBypassDetector.h b/clang/lib/CodeGen/VarBypassDetector.h
index edcf17d1edd24..e456aced2bf46 100644
--- a/clang/lib/CodeGen/VarBypassDetector.h
+++ b/clang/lib/CodeGen/VarBypassDetector.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
@@ -43,7 +44,7 @@ class VarBypassDetector {
// declaration.
llvm::SmallVector<std::pair<unsigned, const VarDecl *>, 48> Scopes;
// List of jumps with scopes.
- llvm::SmallVector<std::pair<const Stmt *, unsigned>, 16> FromScopes;
+ llvm::SmallVectorWithFlags<std::pair<const Stmt *, unsigned>, 16> FromScopes;
// Lookup map to find scope for destinations.
llvm::DenseMap<const Stmt *, unsigned> ToScopes;
// Set of variables which were bypassed by some jump.
@@ -53,7 +54,7 @@ class VarBypassDetector {
llvm::DenseMap<const Stmt *, llvm::SmallSetVector<const VarDecl *, 4>>
BypassedVarsAtSource;
// If true assume that all variables are being bypassed.
- bool AlwaysBypassed = false;
+ void setAlwaysBypassed(bool Value) { FromScopes.setFlag(0, Value); }
public:
void Init(CodeGenModule &CGM, const Stmt *Body);
@@ -61,12 +62,12 @@ class VarBypassDetector {
/// Returns true if the variable declaration was by bypassed by any goto or
/// switch statement.
bool IsBypassed(const VarDecl *D) const {
- return AlwaysBypassed || Bypasses.contains(D);
+ return isAlwaysBypassed() || Bypasses.contains(D);
}
/// Returns true if jump sources cannot be determined (e.g. computed gotos),
/// so all variables must be treated as bypassed.
- bool isAlwaysBypassed() const { return AlwaysBypassed; }
+ bool isAlwaysBypassed() const { return FromScopes.getFlag(0); }
/// Returns the variables bypassed by jumps from the given source statement,
/// or nullptr if it bypasses none.
diff --git a/clang/lib/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/DependencyScanning/ModuleDepCollector.cpp
index ed660fc0707ac..eb07730b0c4e2 100644
--- a/clang/lib/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/DependencyScanning/ModuleDepCollector.cpp
@@ -316,7 +316,7 @@ ModuleDepCollector::getInvocationAdjustedForModuleBuildWithoutOutputs(
CowCompilerInvocation CI = CommonInvocation;
CI.getMutLangOpts().ModuleName = Deps.ID.ModuleName;
- CI.getMutFrontendOpts().IsSystemModule = Deps.IsSystem;
+ CI.getMutFrontendOpts().IsSystemModule = Deps.getIsSystem();
// Inputs
InputKind ModuleMapInputKind(CI.getFrontendOpts().DashX.getLanguage(),
@@ -490,7 +490,7 @@ static std::string getModuleContextHash(const ModuleDeps &MD,
HashBuilder.add(getClangFullRepositoryVersion());
HashBuilder.add(serialization::VERSION_MAJOR, serialization::VERSION_MINOR);
llvm::ErrorOr<std::string> CWD = VFS.getCurrentWorkingDirectory();
- if (CWD && !MD.IgnoreCWD)
+ if (CWD && !MD.getIgnoreCWD())
HashBuilder.add(*CWD);
// Hash the BuildInvocation without any input files.
@@ -735,17 +735,17 @@ ModuleDepCollector::handleTopLevelModule(serialization::ModuleFile *MF) {
ModuleDeps &MD = *OwnedMD;
MD.ID.ModuleName = MF->ModuleName;
- MD.IsSystem = M->IsSystem;
+ MD.setIsSystem(M->getIsSystem());
// Start off with the assumption that this module is shareable when there
// are stable directories. As more dependencies are discovered, check if those
// come from the provided directories.
- MD.IsInStableDirectories = !MDC.StableDirs.empty();
+ MD.setIsInStableDirectories(!MDC.StableDirs.empty());
// For modules which use export_as link name, the linked product that of the
// corresponding export_as-named module.
- if (!M->UseExportAsModuleLinkName)
- MD.LinkLibraries = M->LinkLibraries;
+ if (!M->getUseExportAsModuleLinkName())
+ MD.LinkLibraries.assign(M->LinkLibraries.begin(), M->LinkLibraries.end());
ModuleMap &ModMapInfo =
MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
@@ -786,11 +786,11 @@ ModuleDepCollector::handleTopLevelModule(serialization::ModuleFile *MF) {
MDC.ScanInstance.getASTReader()->visitInputFileInfos(
*MF, /*IncludeSystem=*/true,
[&](const serialization::InputFileInfo &IFI, bool IsSystem) {
- if (MD.IsInStableDirectories) {
+ if (MD.getIsInStableDirectories()) {
auto FullFilePath = ASTReader::ResolveImportedPath(
PathBuf, IFI.UnresolvedImportedFilename, MF->BaseDirectory);
- MD.IsInStableDirectories =
- isPathInStableDir(MDC.StableDirs, *FullFilePath);
+ MD.setIsInStableDirectories(
+ isPathInStableDir(MDC.StableDirs, *FullFilePath));
}
if (!(IFI.TopLevel && IFI.ModuleMap))
return;
@@ -860,11 +860,11 @@ ModuleDepCollector::handleTopLevelModule(serialization::ModuleFile *MF) {
// Check provided input paths from the invocation for determining
// IsInStableDirectories.
- if (MD.IsInStableDirectories)
- MD.IsInStableDirectories =
- areOptionsInStableDir(MDC.StableDirs, CI.getHeaderSearchOpts());
+ if (MD.getIsInStableDirectories())
+ MD.setIsInStableDirectories(
+ areOptionsInStableDir(MDC.StableDirs, CI.getHeaderSearchOpts()));
- MD.IgnoreCWD = IgnoreCWD;
+ MD.setIgnoreCWD(IgnoreCWD);
MDC.associateWithContextHash(CI, MD);
// Finish the compiler invocation. Requires dependencies and the context hash.
@@ -885,18 +885,18 @@ void ModuleDepCollector::addAllModuleDeps(serialization::ModuleFile &MF,
for (serialization::ModuleFile *Import : MF.Imports) {
if (MDC.isPrebuiltModule(Import)) {
MD.PrebuiltModuleDeps.push_back(createPrebuiltModuleDep(Import));
- if (MD.IsInStableDirectories) {
+ if (MD.getIsInStableDirectories()) {
auto It = MDC.PrebuiltModulesASTMap.find(
MD.PrebuiltModuleDeps.back().PCMFile);
- MD.IsInStableDirectories =
- It != MDC.PrebuiltModulesASTMap.end() && It->second.isInStableDir();
+ MD.setIsInStableDirectories(It != MDC.PrebuiltModulesASTMap.end() &&
+ It->second.isInStableDir());
}
} else {
if (auto ID = handleTopLevelModule(Import)) {
MD.ClangModuleDeps.push_back(std::move(*ID));
- if (MD.IsInStableDirectories)
- MD.IsInStableDirectories =
- MDC.ModularDeps[Import]->IsInStableDirectories;
+ if (MD.getIsInStableDirectories())
+ MD.setIsInStableDirectories(
+ MDC.ModularDeps[Import]->getIsInStableDirectories());
}
}
}
diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp
index c81c4445a29f9..9cefbb013d2a0 100644
--- a/clang/lib/Driver/Compilation.cpp
+++ b/clang/lib/Driver/Compilation.cpp
@@ -166,14 +166,14 @@ bool Compilation::CleanupFileMap(const ArgStringMap &Files,
int Compilation::ExecuteCommand(const Command &C,
const Command *&FailingCommand,
bool LogOnly) const {
- if ((getDriver().CCPrintOptions ||
- getArgs().hasArg(options::OPT_v)) && !getDriver().CCGenDiagnostics) {
+ if ((getDriver().getCCPrintOptions() || getArgs().hasArg(options::OPT_v)) &&
+ !getDriver().CCGenDiagnostics) {
raw_ostream *OS = &llvm::errs();
std::unique_ptr<llvm::raw_fd_ostream> OwnedStream;
// Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the
// output stream.
- if (getDriver().CCPrintOptions &&
+ if (getDriver().getCCPrintOptions() &&
!getDriver().CCPrintOptionsFilename.empty()) {
std::error_code EC;
OwnedStream.reset(new llvm::raw_fd_ostream(
@@ -188,10 +188,10 @@ int Compilation::ExecuteCommand(const Command &C,
OS = OwnedStream.get();
}
- if (getDriver().CCPrintOptions)
+ if (getDriver().getCCPrintOptions())
*OS << "[Logging clang options]\n";
- C.Print(*OS, "\n", /*Quote=*/getDriver().CCPrintOptions);
+ C.Print(*OS, "\n", /*Quote=*/getDriver().getCCPrintOptions());
}
if (LogOnly)
@@ -370,7 +370,7 @@ void Compilation::ExecuteJobs(const JobList &Jobs,
// In all but CLMode, execute all the jobs unless the necessary inputs for the
// job is missing due to previous failures.
bool CanRunJobsInParallel =
- !LogOnly && !getDriver().CCPrintOptions &&
+ !LogOnly && !getDriver().getCCPrintOptions() &&
!getDriver().CCPrintProcessStats && !getDriver().CCGenDiagnostics &&
!getDriver().IsCLMode() && !getArgs().hasArg(options::OPT_v) &&
Redirects.empty() && !PostCallback;
diff --git a/clang/lib/Driver/CreateASTUnitFromArgs.cpp b/clang/lib/Driver/CreateASTUnitFromArgs.cpp
index 7503cd4465716..253c1f595e18f 100644
--- a/clang/lib/Driver/CreateASTUnitFromArgs.cpp
+++ b/clang/lib/Driver/CreateASTUnitFromArgs.cpp
@@ -129,10 +129,10 @@ std::unique_ptr<ASTUnit> clang::CreateASTUnitFromCommandLine(
VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
AST->FileMgr =
llvm::makeIntrusiveRefCnt<FileManager>(AST->FileSystemOpts, VFS);
- AST->StorePreamblesInMemory = StorePreamblesInMemory;
+ AST->setStorePreamblesInMemory(StorePreamblesInMemory);
AST->PreambleStoragePath = PreambleStoragePath;
AST->ModCache = createCrossProcessModuleCache();
- AST->OnlyLocalDecls = OnlyLocalDecls;
+ AST->setOnlyLocalDeclsFlag(OnlyLocalDecls);
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->TUKind = TUKind;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a9a21175af9c5..9f517f621232d 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -205,12 +205,12 @@ Driver::Driver(StringRef DriverExecutable, StringRef TargetTriple,
SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone),
Offload(OffloadHostDevice), CXX20HeaderType(HeaderMode_None),
ModulesModeCXX20(false), DriverExecutable(DriverExecutable),
- SysRoot(DEFAULT_SYSROOT), DriverTitle(Title), CCCPrintBindings(false),
- CCPrintOptions(false), CCLogDiagnostics(false), CCGenDiagnostics(false),
- CCPrintProcessStats(false), CCPrintInternalStats(false),
- TargetTriple(TargetTriple), Saver(Alloc), PrependArg(nullptr),
- PreferredLinker(CLANG_DEFAULT_LINKER), CheckInputsExist(true),
- ProbePrecompiled(true), SuppressMissingInputWarning(false) {
+ SysRoot(DEFAULT_SYSROOT), DriverTitle(Title), CCLogDiagnostics(false),
+ CCGenDiagnostics(false), CCPrintProcessStats(false),
+ CCPrintInternalStats(false), TargetTriple(TargetTriple), Saver(Alloc),
+ PrependArg(nullptr), PreferredLinker(CLANG_DEFAULT_LINKER),
+ CheckInputsExist(true), ProbePrecompiled(true),
+ SuppressMissingInputWarning(false) {
// Provide a sane fallback if no VFS is specified.
if (!this->VFS)
this->VFS = llvm::vfs::getRealFileSystem();
@@ -1597,7 +1597,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
// options, either by introducing new ones or by overloading gcc ones like -V
// or -b.
CCCPrintPhases = Args.hasArg(options::OPT_ccc_print_phases);
- CCCPrintBindings = Args.hasArg(options::OPT_ccc_print_bindings);
+ setCCCPrintBindings(Args.hasArg(options::OPT_ccc_print_bindings));
if (const Arg *A = Args.getLastArg(options::OPT_ccc_gcc_name))
CCCGenericGCCName = A->getValue();
@@ -2926,7 +2926,7 @@ static unsigned PrintActions1(const Compilation &C, Action *A,
SibKind = OtherSibAction;
});
} else {
- const ActionList *AL = &A->getInputs();
+ const auto *AL = &A->getInputs();
if (AL->size()) {
const char *Prefix = "{";
@@ -4847,7 +4847,7 @@ class ToolSelector final {
/// Get previous dependent action or null if that does not exist. If
/// \a CanBeCollapsed is false, that action must be legal to collapse or
/// null will be returned.
- const JobAction *getPrevDependentAction(const ActionList &Inputs,
+ const JobAction *getPrevDependentAction(ArrayRef<Action *> Inputs,
ActionList &SavedOffloadAction,
bool CanBeCollapsed = true) {
// An option can be collapsed only if it has a single input.
@@ -4969,7 +4969,7 @@ class ToolSelector final {
if (!T->hasIntegratedAssembler())
return nullptr;
- Inputs = CJ->getInputs();
+ Inputs.assign(CJ->getInputs().begin(), CJ->getInputs().end());
AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
/*NumElements=*/3);
return T;
@@ -4992,7 +4992,7 @@ class ToolSelector final {
if (!T->hasIntegratedAssembler())
return nullptr;
- Inputs = BJ->getInputs();
+ Inputs.assign(BJ->getInputs().begin(), BJ->getInputs().end());
AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
/*NumElements=*/2);
return T;
@@ -5037,7 +5037,7 @@ class ToolSelector final {
if (T->canEmitIR() && EmbedBitcode)
return nullptr;
- Inputs = CJ->getInputs();
+ Inputs.assign(CJ->getInputs().begin(), CJ->getInputs().end());
AppendCollapsedOffloadAction(CollapsedOffloadAction, ActionInfo,
/*NumElements=*/2);
return T;
@@ -5122,7 +5122,8 @@ class ToolSelector final {
if (!T)
T = combineBackendCompile(ActionChain, Inputs, CollapsedOffloadAction);
if (!T) {
- Inputs = BaseAction->getInputs();
+ Inputs.assign(BaseAction->getInputs().begin(),
+ BaseAction->getInputs().end());
T = TC.SelectTool(*BaseAction);
}
@@ -5351,8 +5352,7 @@ InputInfoList Driver::BuildJobsForActionNoCache(
TargetDeviceOffloadKind);
}
-
- ActionList Inputs = A->getInputs();
+ ActionList Inputs(A->getInputs().begin(), A->getInputs().end());
const JobAction *JA = cast<JobAction>(A);
ActionList CollapsedOffloadActions;
@@ -5445,7 +5445,7 @@ InputInfoList Driver::BuildJobsForActionNoCache(
handleTimeTrace(C, Args, JA, BaseInput, Result);
}
- if (CCCPrintBindings && !CCGenDiagnostics) {
+ if (getCCCPrintBindings() && !CCGenDiagnostics) {
llvm::errs() << "# \"" << T->getToolChain().getEffectiveTriple().str()
<< '"' << " - \"" << T->getName() << "\", inputs: [";
for (unsigned i = 0, e = InputInfos.size(); i != e; ++i) {
@@ -5872,8 +5872,8 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const {
// Search for Name in a list of paths.
- auto SearchPaths = [&](const llvm::SmallVectorImpl<std::string> &P)
- -> std::optional<std::string> {
+ auto SearchPaths =
+ [&](llvm::ArrayRef<std::string> P) -> std::optional<std::string> {
// Respect a limited subset of the '-Bprefix' functionality in GCC by
// attempting to use this prefix when looking for file paths.
for (const auto &Dir : P) {
diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp
index 473fe940d9970..16f30d9d3dc8a 100644
--- a/clang/lib/Driver/OffloadBundler.cpp
+++ b/clang/lib/Driver/OffloadBundler.cpp
@@ -112,7 +112,7 @@ bool OffloadTargetInfo::isOffloadKindCompatible(
(OffloadKind == "hipv4" && TargetOffloadKind == "hip"))
return true;
- if (BundlerConfig.HipOpenmpCompatible) {
+ if (BundlerConfig.getHipOpenmpCompatible()) {
bool HIPCompatibleWithOpenMP = OffloadKind.starts_with_insensitive("hip") &&
TargetOffloadKind == "openmp";
bool OpenMPCompatibleWithHIP =
@@ -714,7 +714,7 @@ class ObjectFileHandler final : public FileHandler {
Error executeObjcopy(StringRef Objcopy, ArrayRef<StringRef> Args) {
// If the user asked for the commands to be printed out, we do that
// instead of executing it.
- if (BundlerConfig.PrintExternalCommands) {
+ if (BundlerConfig.getPrintExternalCommands()) {
errs() << "\"" << Objcopy << "\"";
for (StringRef Arg : drop_begin(Args, 1))
errs() << " \"" << Arg << "\"";
@@ -965,11 +965,11 @@ OffloadBundlerConfig::OffloadBundlerConfig()
return;
auto VerboseEnvVarOpt = llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_VERBOSE");
if (VerboseEnvVarOpt.has_value())
- Verbose = VerboseEnvVarOpt.value() == "1";
+ setVerbose(VerboseEnvVarOpt.value() == "1");
auto CompressEnvVarOpt =
llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_COMPRESS");
if (CompressEnvVarOpt.has_value())
- Compress = CompressEnvVarOpt.value() == "1";
+ setCompress(CompressEnvVarOpt.value() == "1");
auto CompressionLevelEnvVarOpt =
llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_COMPRESSION_LEVEL");
if (CompressionLevelEnvVarOpt.has_value()) {
@@ -1064,7 +1064,7 @@ Error OffloadBundler::ListBundleIDsInFile(
// Decompress the input if necessary.
Expected<std::unique_ptr<MemoryBuffer>> DecompressedBufferOrErr =
CompressedOffloadBundle::decompress(
- **CodeOrErr, BundlerConfig.Verbose ? &llvm::errs() : nullptr);
+ **CodeOrErr, BundlerConfig.getVerbose() ? &llvm::errs() : nullptr);
if (!DecompressedBufferOrErr)
return createStringError(
inconvertibleErrorCode(),
@@ -1189,12 +1189,14 @@ Error OffloadBundler::BundleFiles() {
}
// Get the file handler. We use the host buffer as reference.
- assert((BundlerConfig.HostInputIndex != ~0u || BundlerConfig.AllowNoHost) &&
- "Host input index undefined??");
- Expected<std::unique_ptr<FileHandler>> FileHandlerOrErr = CreateFileHandler(
- *InputBuffers[BundlerConfig.AllowNoHost ? 0
- : BundlerConfig.HostInputIndex],
- BundlerConfig);
+ assert(
+ (BundlerConfig.HostInputIndex != ~0u || BundlerConfig.getAllowNoHost()) &&
+ "Host input index undefined??");
+ Expected<std::unique_ptr<FileHandler>> FileHandlerOrErr =
+ CreateFileHandler(*InputBuffers[BundlerConfig.getAllowNoHost()
+ ? 0
+ : BundlerConfig.HostInputIndex],
+ BundlerConfig);
if (!FileHandlerOrErr)
return FileHandlerOrErr.takeError();
@@ -1224,7 +1226,7 @@ Error OffloadBundler::BundleFiles() {
return createFileError(BundlerConfig.OutputFileNames.front(), EC);
SmallVector<char, 0> CompressedBuffer;
- if (BundlerConfig.Compress) {
+ if (BundlerConfig.getCompress()) {
std::unique_ptr<llvm::MemoryBuffer> BufferMemory =
llvm::MemoryBuffer::getMemBufferCopy(
llvm::StringRef(Buffer.data(), Buffer.size()));
@@ -1232,7 +1234,7 @@ Error OffloadBundler::BundleFiles() {
{BundlerConfig.CompressionFormat, BundlerConfig.CompressionLevel,
/*zstdEnableLdm=*/true},
*BufferMemory, BundlerConfig.CompressedBundleVersion,
- BundlerConfig.Verbose ? &llvm::errs() : nullptr);
+ BundlerConfig.getVerbose() ? &llvm::errs() : nullptr);
if (auto Error = CompressionResult.takeError())
return Error;
@@ -1315,7 +1317,7 @@ Error OffloadBundler::UnbundleFiles() {
// Decompress the blob if necessary.
Expected<std::unique_ptr<MemoryBuffer>> DecompressedBufferOrErr =
CompressedOffloadBundle::decompress(
- **BlobOrErr, BundlerConfig.Verbose ? &llvm::errs() : nullptr);
+ **BlobOrErr, BundlerConfig.getVerbose() ? &llvm::errs() : nullptr);
if (!DecompressedBufferOrErr)
return createStringError(
inconvertibleErrorCode(),
@@ -1386,7 +1388,7 @@ Error OffloadBundler::UnbundleFiles() {
Offset += NextBundleStart;
}
- if (!BundlerConfig.AllowMissingBundles && !Worklist.empty()) {
+ if (!BundlerConfig.getAllowMissingBundles() && !Worklist.empty()) {
std::string ErrMsg = "Can't find bundles for";
std::set<StringRef> Sorted;
for (auto &E : Worklist)
@@ -1428,7 +1430,7 @@ Error OffloadBundler::UnbundleFiles() {
// If we found elements, we emit an error if none of those were for the host
// in case host bundle name was provided in command line.
if (!(FoundHostBundle || BundlerConfig.HostInputIndex == ~0u ||
- BundlerConfig.AllowMissingBundles))
+ BundlerConfig.getAllowMissingBundles()))
return createStringError(inconvertibleErrorCode(),
"Can't find bundle for the host target");
@@ -1574,7 +1576,7 @@ Error OffloadBundler::UnbundleArchive() {
StringRef IFName = BundlerConfig.InputFileNames.front();
- if (BundlerConfig.CheckInputArchive) {
+ if (BundlerConfig.getCheckInputArchive()) {
// For a specific processor, a feature either shows up in all target IDs, or
// does not show up in any target IDs. Otherwise the target ID combination
// is invalid.
@@ -1622,7 +1624,7 @@ Error OffloadBundler::UnbundleArchive() {
Expected<std::unique_ptr<MemoryBuffer>> DecompressedBufferOrErr =
CompressedOffloadBundle::decompress(
*TempCodeObjectBuffer,
- BundlerConfig.Verbose ? &llvm::errs() : nullptr);
+ BundlerConfig.getVerbose() ? &llvm::errs() : nullptr);
if (!DecompressedBufferOrErr)
return createStringError(
inconvertibleErrorCode(),
@@ -1720,7 +1722,7 @@ Error OffloadBundler::UnbundleArchive() {
getDefaultArchiveKindForHost(), true,
false, nullptr))
return WriteErr;
- } else if (!BundlerConfig.AllowMissingBundles) {
+ } else if (!BundlerConfig.getAllowMissingBundles()) {
std::string ErrMsg =
Twine("no compatible code object found for the target '" + Target +
"' in heterogeneous archive library: " + IFName)
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 255a9c9602b54..2c944023e0266 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -536,6 +536,7 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
SanitizerArgs
ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs, BoundArch BA,
Action::OffloadKind DeviceOffloadKind) const {
+ const bool DiagnoseErrors = BoundArchSanitizerArgsChecked.empty();
// When -fno-gpu-sanitize is specified for GPU targets, don't emit
// diagnostics about unsupported sanitizers for specific GPU arches,
// since sanitizers are disabled for the GPU anyway.
@@ -547,11 +548,9 @@ ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs, BoundArch BA,
DiagnoseBoundArchErrors = false;
}
- SanitizerArgs SanArgs(*this, JobArgs,
- /*DiagnoseErrors=*/!SanitizerArgsChecked,
- DiagnoseBoundArchErrors, BA, DeviceOffloadKind);
+ SanitizerArgs SanArgs(*this, JobArgs, DiagnoseErrors, DiagnoseBoundArchErrors,
+ BA, DeviceOffloadKind);
- SanitizerArgsChecked = true;
return SanArgs;
}
diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp
index 54ef9bb27993a..0c681f5100675 100644
--- a/clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -184,7 +184,7 @@ bool RocmInstallationDetector::parseHIPVersionFile(llvm::StringRef V) {
/// \returns a list of candidate directories for ROCm installation, which is
/// cached and populated only once.
-const SmallVectorImpl<RocmInstallationDetector::Candidate> &
+ArrayRef<RocmInstallationDetector::Candidate>
RocmInstallationDetector::getInstallationPathCandidates() {
// Return the cached candidate list if it has already been populated.
@@ -192,7 +192,7 @@ RocmInstallationDetector::getInstallationPathCandidates() {
return ROCmSearchDirs;
auto DoPrintROCmSearchDirs = [&]() {
- if (PrintROCmSearchDirs)
+ if (getPrintROCmSearchDirs())
for (auto Cand : ROCmSearchDirs) {
llvm::errs() << "ROCm installation search path: " << Cand.Path << '\n';
}
@@ -318,9 +318,9 @@ RocmInstallationDetector::RocmInstallationDetector(
const Driver &D, const llvm::Triple &HostTriple,
const llvm::opt::ArgList &Args, bool DetectHIPRuntime)
: D(D) {
- Verbose = Args.hasArg(options::OPT_v);
+ setVerbose(Args.hasArg(options::OPT_v));
RocmPathArg = Args.getLastArgValue(options::OPT_rocm_path_EQ);
- PrintROCmSearchDirs = Args.hasArg(options::OPT_print_rocm_search_dirs);
+ setPrintROCmSearchDirs(Args.hasArg(options::OPT_print_rocm_search_dirs));
RocmDeviceLibPathArg =
Args.getAllArgValues(options::OPT_rocm_device_lib_path_EQ);
HIPPathArg = Args.getLastArgValue(options::OPT_hip_path_EQ);
@@ -396,13 +396,13 @@ void RocmInstallationDetector::detectDeviceLibrary() {
// Check device library exists at the given path.
auto CheckDeviceLib = [&](StringRef Path, bool StrictChecking) {
- bool CheckLibDevice = (!NoBuiltinLibs || StrictChecking);
+ bool CheckLibDevice = (!getNoBuiltinLibs() || StrictChecking);
if (CheckLibDevice && !FS.exists(Path))
return false;
scanLibDevicePath(Path);
- if (!NoBuiltinLibs) {
+ if (!getNoBuiltinLibs()) {
// Check that the required non-target libraries are all available.
if (!allGenericLibsValid())
return false;
@@ -425,7 +425,7 @@ void RocmInstallationDetector::detectDeviceLibrary() {
// Find device libraries in a legacy ROCm directory structure
// ${ROCM_ROOT}/amdgcn/bitcode/*
- auto &ROCmDirs = getInstallationPathCandidates();
+ auto ROCmDirs = getInstallationPathCandidates();
for (const auto &Candidate : ROCmDirs) {
LibDevicePath = Candidate.Path;
llvm::sys::path::append(LibDevicePath, "amdgcn", "bitcode");
@@ -446,7 +446,7 @@ void RocmInstallationDetector::detectHIPRuntime(
HIPSearchDirs.emplace_back(std::move(*HIPPathEnv));
}
if (HIPSearchDirs.empty())
- HIPSearchDirs.append(getInstallationPathCandidates());
+ llvm::append_range(HIPSearchDirs, getInstallationPathCandidates());
auto &FS = D.getVFS();
for (const auto &Candidate : HIPSearchDirs) {
diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp
index ec2641301909d..014c9264604c6 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -562,9 +562,9 @@ void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
/// Hexagon Toolchain
-std::string HexagonToolChain::getHexagonTargetDir(
- const std::string &InstalledDir,
- const SmallVectorImpl<std::string> &PrefixDirs) const {
+std::string
+HexagonToolChain::getHexagonTargetDir(const std::string &InstalledDir,
+ ArrayRef<std::string> PrefixDirs) const {
const Driver &D = getDriver();
// Locate the rest of the toolchain ...
diff --git a/clang/lib/Driver/ToolChains/Hexagon.h b/clang/lib/Driver/ToolChains/Hexagon.h
index 1f848a8de061d..f4c471c3b2ba2 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.h
+++ b/clang/lib/Driver/ToolChains/Hexagon.h
@@ -105,9 +105,8 @@ class LLVM_LIBRARY_VISIBILITY HexagonToolChain : public Linux {
StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; }
- std::string getHexagonTargetDir(
- const std::string &InstalledDir,
- const SmallVectorImpl<std::string> &PrefixDirs) const;
+ std::string getHexagonTargetDir(const std::string &InstalledDir,
+ ArrayRef<std::string> PrefixDirs) const;
SmallString<128> getEffectiveSysRoot(const llvm::opt::ArgList &Args) const;
void getBaseIncludeDir(const llvm::opt::ArgList &Args,
llvm::SmallString<128> &) const;
diff --git a/clang/lib/Edit/Commit.cpp b/clang/lib/Edit/Commit.cpp
index 415b1573d789a..2b82ca7eabc4b 100644
--- a/clang/lib/Edit/Commit.cpp
+++ b/clang/lib/Edit/Commit.cpp
@@ -52,7 +52,7 @@ bool Commit::insert(SourceLocation loc, StringRef text,
FileOffset Offs;
if ((!afterToken && !canInsert(loc, Offs)) ||
( afterToken && !canInsertAfterToken(loc, Offs, loc))) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
@@ -66,20 +66,20 @@ bool Commit::insertFromRange(SourceLocation loc,
FileOffset RangeOffs;
unsigned RangeLen;
if (!canRemoveRange(range, RangeOffs, RangeLen)) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
FileOffset Offs;
if ((!afterToken && !canInsert(loc, Offs)) ||
( afterToken && !canInsertAfterToken(loc, Offs, loc))) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
if (PPRec &&
PPRec->areInDifferentConditionalDirectiveRegion(loc, range.getBegin())) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
@@ -91,7 +91,7 @@ bool Commit::remove(CharSourceRange range) {
FileOffset Offs;
unsigned Len;
if (!canRemoveRange(range, Offs, Len)) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
@@ -119,7 +119,7 @@ bool Commit::replace(CharSourceRange range, StringRef text) {
FileOffset Offs;
unsigned Len;
if (!canInsert(range.getBegin(), Offs) || !canRemoveRange(range, Offs, Len)) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
@@ -133,14 +133,14 @@ bool Commit::replaceWithInner(CharSourceRange range,
FileOffset OuterBegin;
unsigned OuterLen;
if (!canRemoveRange(range, OuterBegin, OuterLen)) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
FileOffset InnerBegin;
unsigned InnerLen;
if (!canRemoveRange(replacementRange, InnerBegin, InnerLen)) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
@@ -150,7 +150,7 @@ bool Commit::replaceWithInner(CharSourceRange range,
InnerBegin < OuterBegin ||
InnerBegin > OuterEnd ||
InnerEnd > OuterEnd) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
@@ -169,7 +169,7 @@ bool Commit::replaceText(SourceLocation loc, StringRef text,
FileOffset Offs;
unsigned Len;
if (!canReplaceText(loc, replacementText, Offs, Len)) {
- IsCommitable = false;
+ setIsCommitable(false);
return false;
}
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 6228f2e687be2..3d1afed88df9c 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -605,8 +605,7 @@ void serializeTemplateMixin(Object &Paren, const RecordTy &Record) {
serializeObject(Paren, "swiftGenerics", Generics);
}
-Array generateParentContexts(const SmallVectorImpl<SymbolReference> &Parents,
- Language Lang) {
+Array generateParentContexts(ArrayRef<SymbolReference> Parents, Language Lang) {
Array ParentContexts;
for (const auto &Parent : Parents) {
@@ -703,7 +702,7 @@ bool SymbolGraphSerializer::shouldSkip(const APIRecord *Record) const {
}
ExtendedModule &SymbolGraphSerializer::getModuleForCurrentSymbol() {
- if (!ForceEmitToMainModule && ModuleForCurrentSymbol)
+ if (!getForceEmitToMainModule() && ModuleForCurrentSymbol)
return *ModuleForCurrentSymbol;
return MainModule;
@@ -734,7 +733,7 @@ void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind,
ExtendedModule &Into) {
Object Relationship;
SmallString<64> TestRelLabel;
- if (EmitSymbolLabelsForTesting) {
+ if (getEmitSymbolLabelsForTesting()) {
llvm::raw_svector_ostream OS(TestRelLabel);
OS << SymbolGraphSerializer::getRelationshipString(Kind) << " $ "
<< Source.USR << " $ ";
@@ -749,7 +748,7 @@ void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind,
Relationship["targetFallback"] = Target.Name;
Relationship["kind"] = SymbolGraphSerializer::getRelationshipString(Kind);
- if (ForceEmitToMainModule)
+ if (getForceEmitToMainModule())
MainModule.addRelationship(std::move(Relationship));
else
Into.addRelationship(std::move(Relationship));
@@ -770,7 +769,7 @@ void SymbolGraphSerializer::serializeAPIRecord(const APIRecord *Record) {
// If we need symbol labels for testing emit the USR as the value and the key
// starts with '!'' to ensure it ends up at the top of the object.
- if (EmitSymbolLabelsForTesting)
+ if (getEmitSymbolLabelsForTesting())
Obj["!testLabel"] = Record->USR;
serializeObject(Obj, "identifier",
@@ -940,7 +939,7 @@ bool SymbolGraphSerializer::visitObjCInterfaceRecord(
bool SymbolGraphSerializer::traverseObjCCategoryRecord(
const ObjCCategoryRecord *Record) {
- if (SkipSymbolsInCategoriesToExternalTypes &&
+ if (getSkipSymbolsInCategoriesToExternalTypes() &&
!API.findRecordForUSR(Record->Interface.USR))
return true;
@@ -1105,7 +1104,7 @@ SymbolGraphSerializer::serializeSingleSymbolSGF(StringRef USR,
/*ForceEmitToMainModule*/ true);
// Set up serializer parent chain
- Serializer.Hierarchy = generateHierarchyFromRecord(Record);
+ Serializer.Hierarchy.assign(generateHierarchyFromRecord(Record));
Serializer.serializeSingleRecord(Record);
serializeObject(Root, "symbolGraph",
diff --git a/clang/lib/Format/AffectedRangeManager.cpp b/clang/lib/Format/AffectedRangeManager.cpp
index 7e9acc9fbbb04..1f37ce64e5aa6 100644
--- a/clang/lib/Format/AffectedRangeManager.cpp
+++ b/clang/lib/Format/AffectedRangeManager.cpp
@@ -20,7 +20,7 @@ namespace clang {
namespace format {
bool AffectedRangeManager::computeAffectedLines(
- SmallVectorImpl<AnnotatedLine *> &Lines) {
+ ArrayRef<AnnotatedLine *> Lines) {
ArrayRef<AnnotatedLine *>::iterator I = Lines.begin();
ArrayRef<AnnotatedLine *>::iterator E = Lines.end();
bool SomeLineAffected = false;
@@ -99,9 +99,9 @@ void AffectedRangeManager::markAllAsAffected(
}
}
-bool AffectedRangeManager::nonPPLineAffected(
- AnnotatedLine *Line, const AnnotatedLine *PreviousLine,
- SmallVectorImpl<AnnotatedLine *> &Lines) {
+bool AffectedRangeManager::nonPPLineAffected(AnnotatedLine *Line,
+ const AnnotatedLine *PreviousLine,
+ ArrayRef<AnnotatedLine *> Lines) {
bool SomeLineAffected = false;
Line->ChildrenAffected = computeAffectedLines(Line->Children);
if (Line->ChildrenAffected)
diff --git a/clang/lib/Format/AffectedRangeManager.h b/clang/lib/Format/AffectedRangeManager.h
index eef056fdf0633..fca8108cb4856 100644
--- a/clang/lib/Format/AffectedRangeManager.h
+++ b/clang/lib/Format/AffectedRangeManager.h
@@ -31,7 +31,7 @@ class AffectedRangeManager {
// Determines which lines are affected by the SourceRanges given as input.
// Returns \c true if at least one line in \p Lines or one of their
// children is affected.
- bool computeAffectedLines(SmallVectorImpl<AnnotatedLine *> &Lines);
+ bool computeAffectedLines(ArrayRef<AnnotatedLine *> Lines);
// Returns true if 'Range' intersects with one of the input ranges.
bool affectsCharSourceRange(const CharSourceRange &Range);
@@ -53,7 +53,7 @@ class AffectedRangeManager {
// Determines whether 'Line' is affected by the SourceRanges given as input.
// Returns \c true if line or one if its children is affected.
bool nonPPLineAffected(AnnotatedLine *Line, const AnnotatedLine *PreviousLine,
- SmallVectorImpl<AnnotatedLine *> &Lines);
+ ArrayRef<AnnotatedLine *> Lines);
const SourceManager &SourceMgr;
const SmallVector<CharSourceRange, 8> Ranges;
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index bb8179cbc4f95..2c0ebfc7a28f5 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -347,12 +347,12 @@ LineState ContinuationIndenter::getInitialState(unsigned FirstIndent,
State.Stack.push_back(ParenState(/*Tok=*/nullptr, FirstIndent, FirstIndent,
/*AvoidBinPacking=*/false,
/*NoLineBreak=*/false));
- State.NoContinuation = false;
+ State.setNoContinuation(false);
State.StartOfStringLiteral = 0;
- State.NoLineBreak = false;
+ State.setNoLineBreak(false);
State.StartOfLineLevel = 0;
State.LowestLevelOnLine = 0;
- State.IgnoreStackForComparison = false;
+ State.setIgnoreStackForComparison(false);
if (Style.isTextProto()) {
// We need this in order to deal with the bin packing of text fields at
@@ -468,7 +468,7 @@ bool ContinuationIndenter::canBreak(const LineState &State) {
return true;
}
- return !State.NoLineBreak && !CurrentState.NoLineBreak;
+ return !State.getNoLineBreak() && !CurrentState.NoLineBreak;
}
bool ContinuationIndenter::mustBreak(const LineState &State) {
@@ -707,7 +707,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
}
if (Current.is(TT_FunctionDeclarationName) &&
- !State.Line->ReturnTypeWrapped &&
+ !State.Line->getReturnTypeWrapped() &&
// Don't break before a C# function when no break after return type.
(!Style.isCSharp() ||
Style.BreakAfterReturnType > FormatStyle::RTBS_ExceptShortType) &&
@@ -749,7 +749,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
if (Previous.is(TT_BlockComment) && Previous.IsMultiline)
return true;
- if (State.NoContinuation)
+ if (State.getNoContinuation())
return true;
return false;
@@ -763,7 +763,7 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline,
const FormatToken &Previous = *State.NextToken->Previous;
assert(!State.Stack.empty());
- State.NoContinuation = false;
+ State.setNoContinuation(false);
if (Current.is(TT_ImplicitStringLiteral) &&
(!Previous.Tok.getIdentifierInfo() ||
@@ -850,7 +850,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
};
if (DisallowLineBreaks())
- State.NoLineBreak = true;
+ State.setNoLineBreak(true);
if (Current.is(tok::equal) &&
(State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&
@@ -1031,7 +1031,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
Previous.isNoneOf(TT_ObjCMethodExpr, TT_RequiresClause,
TT_TableGenDAGArgOpener,
TT_TableGenDAGArgOpenerToBreak) &&
- !(Current.MacroParent && Previous.MacroParent) &&
+ !(Current.getMacroParent() && Previous.getMacroParent()) &&
(Current.isNot(TT_LineComment) ||
(Previous.is(BK_BracedInit) &&
Style.Cpp11BracedListStyle != FormatStyle::BLS_FunctionCall) ||
@@ -1698,7 +1698,7 @@ ContinuationIndenter::getNewLineColumn(const LineState &State) {
TT_LeadingJavaAnnotation))) ||
(!Style.IndentWrappedFunctionNames &&
NextNonComment->isOneOf(tok::kw_operator, TT_FunctionDeclarationName)) ||
- (State.Line->ReturnTypeWrapped && PreviousNonComment &&
+ (State.Line->getReturnTypeWrapped() && PreviousNonComment &&
isReturnTypePrefixSpecifier(*PreviousNonComment))) {
return std::max(IndentationAndAlignment(CurrentState.LastSpace),
CurrentState.Indent);
@@ -3134,7 +3134,7 @@ ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
Paren.BreakBeforeParameter = true;
if (Current.is(TT_BlockComment))
- State.NoContinuation = true;
+ State.setNoContinuation(true);
State.Stack.back().LastSpace = StartColumn;
}
diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h
index ed347591525ea..972b4759e21f2 100644
--- a/clang/lib/Format/ContinuationIndenter.h
+++ b/clang/lib/Format/ContinuationIndenter.h
@@ -17,6 +17,7 @@
#include "Encoding.h"
#include "FormatToken.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
class SourceManager;
@@ -459,7 +460,11 @@ struct LineState {
FormatToken *NextToken;
/// \c true if \p NextToken should not continue this line.
- bool NoContinuation;
+ bool getNoContinuation() const { return Stack.getFlag(0); }
+ bool setNoContinuation(bool Value) {
+ Stack.setFlag(0, Value);
+ return Value;
+ }
/// The \c NestingLevel at the start of this line.
unsigned StartOfLineLevel;
@@ -472,11 +477,18 @@ struct LineState {
unsigned StartOfStringLiteral;
/// Disallow line breaks for this line.
- bool NoLineBreak;
+ bool getNoLineBreak() const { return Stack.getFlag(1); }
+ bool setNoLineBreak(bool Value) {
+ Stack.setFlag(1, Value);
+ return Value;
+ }
/// A stack keeping track of properties applying to parenthesis
/// levels.
- SmallVector<ParenState> Stack;
+ llvm::SmallVectorWithFlags<
+ ParenState,
+ llvm::CalculateSmallVectorDefaultInlinedElements<ParenState>::value, 3>
+ Stack;
/// Ignore the stack of \c ParenStates for state comparison.
///
@@ -491,7 +503,11 @@ struct LineState {
/// later.
///
/// FIXME: Come up with a better algorithm instead.
- bool IgnoreStackForComparison;
+ bool getIgnoreStackForComparison() const { return Stack.getFlag(2); }
+ bool setIgnoreStackForComparison(bool Value) {
+ Stack.setFlag(2, Value);
+ return Value;
+ }
/// The indent of the first token.
unsigned FirstIndent;
@@ -507,17 +523,17 @@ struct LineState {
return NextToken < Other.NextToken;
if (Column != Other.Column)
return Column < Other.Column;
- if (NoContinuation != Other.NoContinuation)
- return NoContinuation;
+ if (getNoContinuation() != Other.getNoContinuation())
+ return getNoContinuation();
if (StartOfLineLevel != Other.StartOfLineLevel)
return StartOfLineLevel < Other.StartOfLineLevel;
if (LowestLevelOnLine != Other.LowestLevelOnLine)
return LowestLevelOnLine < Other.LowestLevelOnLine;
if (StartOfStringLiteral != Other.StartOfStringLiteral)
return StartOfStringLiteral < Other.StartOfStringLiteral;
- if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
+ if (getIgnoreStackForComparison() || Other.getIgnoreStackForComparison())
return false;
- return Stack < Other.Stack;
+ return llvm::ArrayRef(Stack) < llvm::ArrayRef(Other.Stack);
}
};
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index c4baf8002c274..1e6093d674680 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -24,6 +24,7 @@
#include "UsingDeclarationsSorter.h"
#include "clang/Tooling/Inclusions/HeaderIncludes.h"
#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/VirtualFileSystem.h"
@@ -2699,7 +2700,7 @@ class ParensRemover : public TokenAnalyzer {
}
private:
- void removeParens(SmallVectorImpl<AnnotatedLine *> &Lines,
+ void removeParens(ArrayRef<AnnotatedLine *> Lines,
tooling::Replacements &Result) {
const auto &SourceMgr = Env.getSourceManager();
for (auto *Line : Lines) {
@@ -2732,7 +2733,7 @@ class BracesInserter : public TokenAnalyzer {
}
private:
- void insertBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
+ void insertBraces(ArrayRef<AnnotatedLine *> Lines,
tooling::Replacements &Result) {
const auto &SourceMgr = Env.getSourceManager();
int OpeningBraceSurplus = 0;
@@ -2786,7 +2787,7 @@ class BracesRemover : public TokenAnalyzer {
}
private:
- void removeBraces(SmallVectorImpl<AnnotatedLine *> &Lines,
+ void removeBraces(ArrayRef<AnnotatedLine *> Lines,
tooling::Replacements &Result) {
const auto &SourceMgr = Env.getSourceManager();
const auto *End = Lines.end();
@@ -2827,8 +2828,7 @@ class SemiRemover : public TokenAnalyzer {
}
private:
- void removeSemi(TokenAnnotator &Annotator,
- SmallVectorImpl<AnnotatedLine *> &Lines,
+ void removeSemi(TokenAnnotator &Annotator, ArrayRef<AnnotatedLine *> Lines,
tooling::Replacements &Result) {
auto PrecededByFunctionRBrace = [](const FormatToken &Tok) {
const auto *Prev = Tok.Previous;
@@ -2879,7 +2879,7 @@ class EnumTrailingCommaEditor : public TokenAnalyzer {
}
private:
- void editEnumTrailingComma(SmallVectorImpl<AnnotatedLine *> &Lines,
+ void editEnumTrailingComma(ArrayRef<AnnotatedLine *> Lines,
tooling::Replacements &Result) {
bool InEnumBraces = false;
FormatToken *BeforeRBrace = nullptr;
@@ -2933,7 +2933,7 @@ class JavaScriptRequoter : public TokenAnalyzer {
private:
// Replaces double/single-quoted string literal as appropriate, re-escaping
// the contents in the process.
- void requoteJSStringLiteral(SmallVectorImpl<AnnotatedLine *> &Lines,
+ void requoteJSStringLiteral(ArrayRef<AnnotatedLine *> Lines,
tooling::Replacements &Result) {
for (AnnotatedLine *Line : Lines) {
requoteJSStringLiteral(Line->Children, Result);
@@ -3047,8 +3047,7 @@ class Formatter : public TokenAnalyzer {
}
private:
- bool
- hasCpp03IncompatibleFormat(const SmallVectorImpl<AnnotatedLine *> &Lines) {
+ bool hasCpp03IncompatibleFormat(ArrayRef<AnnotatedLine *> Lines) {
for (const AnnotatedLine *Line : Lines) {
if (hasCpp03IncompatibleFormat(Line->Children))
return true;
@@ -3066,7 +3065,7 @@ class Formatter : public TokenAnalyzer {
return false;
}
- int countVariableAlignments(const SmallVectorImpl<AnnotatedLine *> &Lines) {
+ int countVariableAlignments(ArrayRef<AnnotatedLine *> Lines) {
int AlignmentDiff = 0;
for (const AnnotatedLine *Line : Lines) {
@@ -3176,7 +3175,7 @@ class TrailingCommaInserter : public TokenAnalyzer {
private:
/// Inserts trailing commas in [] and {} initializers if they wrap over
/// multiple lines.
- void insertTrailingCommas(SmallVectorImpl<AnnotatedLine *> &Lines,
+ void insertTrailingCommas(ArrayRef<AnnotatedLine *> Lines,
tooling::Replacements &Result) {
for (AnnotatedLine *Line : Lines) {
insertTrailingCommas(Line->Children, Result);
@@ -3461,10 +3460,9 @@ class ObjCHeaderStyleGuesser : public TokenAnalyzer {
bool isObjC() { return IsObjC; }
private:
- static bool
- guessIsObjC(const SourceManager &SourceManager,
- const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
- const AdditionalKeywords &Keywords) {
+ static bool guessIsObjC(const SourceManager &SourceManager,
+ ArrayRef<AnnotatedLine *> AnnotatedLines,
+ const AdditionalKeywords &Keywords) {
// Keep this array sorted, since we are binary searching over it.
static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
"CGFloat",
@@ -3594,11 +3592,19 @@ struct IncludeDirective {
};
struct JavaImportDirective {
+ JavaImportDirective(StringRef Identifier, StringRef Text, unsigned Offset,
+ ArrayRef<StringRef> Comments, bool IsStatic)
+ : Identifier(Identifier), Text(Text), Offset(Offset),
+ AssociatedCommentLines(
+ decltype(this->AssociatedCommentLines)::withFlags(
+ unsigned(IsStatic), Comments)) {}
+
StringRef Identifier;
StringRef Text;
unsigned Offset;
- SmallVector<StringRef> AssociatedCommentLines;
- bool IsStatic;
+ llvm::SmallVectorWithFlags<StringRef> AssociatedCommentLines;
+ bool getIsStatic() const { return AssociatedCommentLines.getFlag(0); }
+ void setIsStatic(bool Value) { AssociatedCommentLines.setFlag(0, Value); }
};
} // end anonymous namespace
@@ -4005,10 +4011,10 @@ static void sortJavaImports(const FormatStyle &Style,
Style.SortJavaStaticImport == FormatStyle::SJSIO_After;
sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
// Negating IsStatic to push static imports above non-static imports.
- return std::make_tuple(!Imports[LHSI].IsStatic ^
+ return std::make_tuple(!Imports[LHSI].getIsStatic() ^
StaticImportAfterNormalImport,
JavaImportGroups[LHSI], Imports[LHSI].Identifier) <
- std::make_tuple(!Imports[RHSI].IsStatic ^
+ std::make_tuple(!Imports[RHSI].getIsStatic() ^
StaticImportAfterNormalImport,
JavaImportGroups[RHSI], Imports[RHSI].Identifier);
});
@@ -4020,14 +4026,14 @@ static void sortJavaImports(const FormatStyle &Style,
}),
Indices.end());
- bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
+ bool CurrentIsStatic = Imports[Indices.front()].getIsStatic();
unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
std::string result;
for (unsigned Index : Indices) {
if (!result.empty()) {
result += "\n";
- if (CurrentIsStatic != Imports[Index].IsStatic ||
+ if (CurrentIsStatic != Imports[Index].getIsStatic() ||
CurrentImportGroup != JavaImportGroups[Index]) {
result += "\n";
}
@@ -4037,7 +4043,7 @@ static void sortJavaImports(const FormatStyle &Style,
result += "\n";
}
result += Imports[Index].Text;
- CurrentIsStatic = Imports[Index].IsStatic;
+ CurrentIsStatic = Imports[Index].getIsStatic();
CurrentImportGroup = JavaImportGroups[Index];
}
diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp
index 33e7727f0162d..2de1c742152a1 100644
--- a/clang/lib/Format/FormatToken.cpp
+++ b/clang/lib/Format/FormatToken.cpp
@@ -162,7 +162,7 @@ unsigned CommaSeparatedList::formatFromToken(LineState &State,
bool DryRun) {
// Formatting with 1 Column isn't really a column layout, so we don't need the
// special logic here. We can just avoid bin packing any of the parameters.
- if (Formats.size() == 1 || HasNestedBracedList)
+ if (Formats.size() == 1 || getHasNestedBracedList())
State.Stack.back().AvoidBinPacking = true;
return 0;
}
@@ -224,7 +224,7 @@ void CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) {
MustBreakBeforeItem.push_back(ItemBegin->MustBreakBefore);
if (ItemBegin->is(tok::l_brace))
- HasNestedBracedList = true;
+ setHasNestedBracedList(true);
const FormatToken *ItemEnd = nullptr;
if (i == Commas.size()) {
ItemEnd = Token->MatchingParen;
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 691ecdd24f448..27c991ffc1c20 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -19,6 +19,7 @@
#include "clang/Basic/OperatorPrecedence.h"
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <unordered_set>
namespace clang {
@@ -583,7 +584,7 @@ struct FormatToken {
///
/// If multiple fake parentheses start at a token, this vector stores them in
/// reverse order, i.e. inner fake parenthesis first.
- SmallVector<prec::Level, 4> FakeLParens;
+ llvm::SmallVectorWithFlags<prec::Level, 4> FakeLParens;
/// Insert this many fake ) after this token for correct indentation.
unsigned FakeRParens = 0;
@@ -646,7 +647,8 @@ struct FormatToken {
/// This is deeply baked into the code and disentangling this will require
/// signficant refactorings. \c MacroParent allows us to special-case the
/// cases in which we treat parents as block-openers for now.
- bool MacroParent = false;
+ bool getMacroParent() const { return FakeLParens.getFlag(0); }
+ void setMacroParent(bool Value) { FakeLParens.setFlag(0, Value); }
bool is(tok::TokenKind Kind) const { return Tok.is(Kind); }
bool is(tok::ObjCKeywordKind Kind) const {
@@ -1050,8 +1052,7 @@ class TokenRole {
class CommaSeparatedList : public TokenRole {
public:
- CommaSeparatedList(const FormatStyle &Style)
- : TokenRole(Style), HasNestedBracedList(false) {}
+ CommaSeparatedList(const FormatStyle &Style) : TokenRole(Style) {}
void precomputeFormattingInfos(const FormatToken *Token) override;
@@ -1101,9 +1102,10 @@ class CommaSeparatedList : public TokenRole {
SmallVector<unsigned, 8> ItemLengths;
/// Precomputed formats that can be used for this list.
- SmallVector<ColumnFormat, 4> Formats;
+ llvm::SmallVectorWithFlags<ColumnFormat, 4> Formats;
- bool HasNestedBracedList;
+ bool getHasNestedBracedList() const { return Formats.getFlag(0); }
+ void setHasNestedBracedList(bool Value) { Formats.setFlag(0, Value); }
};
/// Encapsulates keywords that are context sensitive or for languages not
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index 2a8bef21ad414..b6ea8eb9617cf 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -28,13 +28,13 @@ FormatTokenLexer::FormatTokenLexer(
const FormatStyle &Style, encoding::Encoding Encoding,
llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
IdentifierTable &IdentTable)
- : FormatTok(nullptr), IsFirstToken(true), StateStack({LexerState::NORMAL}),
- Column(Column), TrailingWhitespace(0),
- LangOpts(getFormattingLangOpts(Style)), SourceMgr(SourceMgr), ID(ID),
- Style(Style), IdentTable(IdentTable), Keywords(IdentTable),
- Encoding(Encoding), Allocator(Allocator), FirstInLineIndex(0),
- FormattingDisabled(false), MacroBlockBeginRegex(Style.MacroBlockBegin),
- MacroBlockEndRegex(Style.MacroBlockEnd), VerilogProtectedBlock(false) {
+ : FormatTok(nullptr), StateStack({LexerState::NORMAL}), Column(Column),
+ TrailingWhitespace(0), LangOpts(getFormattingLangOpts(Style)),
+ SourceMgr(SourceMgr), ID(ID), Style(Style), IdentTable(IdentTable),
+ Keywords(IdentTable), Encoding(Encoding), Allocator(Allocator),
+ FirstInLineIndex(0), Tokens(decltype(Tokens)::withFlags(1)),
+ MacroBlockBeginRegex(Style.MacroBlockBegin),
+ MacroBlockEndRegex(Style.MacroBlockEnd) {
Lex = std::make_unique<Lexer>(ID, SourceMgr.getBufferOrFake(ID), SourceMgr,
LangOpts);
Lex->SetKeepWhitespaceMode(true);
@@ -111,7 +111,7 @@ ArrayRef<FormatToken *> FormatTokenLexer::lex() {
FormatOff = FO_None;
[[fallthrough]];
default:
- if (!FormattingDisabled && FormatOffRegex.match(Tok.TokenText)) {
+ if (!getFormattingDisabled() && FormatOffRegex.match(Tok.TokenText)) {
if (Tok.is(tok::comment) &&
(NewlinesBefore > 0 || Tokens.size() == 1)) {
Tok.Finalized = true;
@@ -1266,8 +1266,8 @@ FormatToken *FormatTokenLexer::getNextToken() {
readRawToken(*FormatTok);
SourceLocation WhitespaceStart =
FormatTok->Tok.getLocation().getLocWithOffset(-TrailingWhitespace);
- FormatTok->IsFirst = IsFirstToken;
- IsFirstToken = false;
+ FormatTok->IsFirst = getIsFirstToken();
+ setIsFirstToken(false);
// Consume and record whitespace until we find a significant token.
// Some tok::unknown tokens are not just whitespace, e.g. whitespace
@@ -1441,7 +1441,7 @@ FormatToken *FormatTokenLexer::getNextToken() {
Keywords.kw_data_public_key, Keywords.kw_digest_block,
Keywords.kw_digest_decrypt_key, Keywords.kw_digest_public_key,
Keywords.kw_key_block, Keywords.kw_key_public_key)) {
- VerilogProtectedBlock = true;
+ setVerilogProtectedBlock(true);
}
}
} else if (const bool Greater = FormatTok->is(tok::greatergreater);
@@ -1521,9 +1521,9 @@ FormatToken *FormatTokenLexer::getNextToken() {
bool FormatTokenLexer::readVerilogProtected(FormatToken &Tok) {
// The block follows the pragma line.
- if (!VerilogProtectedBlock || Tok.NewlinesBefore == 0)
+ if (!getVerilogProtectedBlock() || Tok.NewlinesBefore == 0)
return false;
- VerilogProtectedBlock = false;
+ setVerilogProtectedBlock(false);
// The block can be empty. Then no token is necessary. A backtick on its own
// line is likely a uuencode line. A backtick followed by something is assumed
@@ -1634,12 +1634,12 @@ void FormatTokenLexer::readRawToken(FormatToken &Tok) {
Tok.Tok.setKind(tok::string_literal);
if (Tok.is(tok::comment) && isClangFormatOn(Tok.TokenText))
- FormattingDisabled = false;
+ setFormattingDisabled(false);
- Tok.Finalized = FormattingDisabled;
+ Tok.Finalized = getFormattingDisabled();
if (Tok.is(tok::comment) && isClangFormatOff(Tok.TokenText))
- FormattingDisabled = true;
+ setFormattingDisabled(true);
}
void FormatTokenLexer::resetLexer(unsigned Offset) {
diff --git a/clang/lib/Format/FormatTokenLexer.h b/clang/lib/Format/FormatTokenLexer.h
index 6fbd05aef7747..baff42e720831 100644
--- a/clang/lib/Format/FormatTokenLexer.h
+++ b/clang/lib/Format/FormatTokenLexer.h
@@ -19,6 +19,7 @@
#include "FormatToken.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringSet.h"
#include <stack>
@@ -113,7 +114,8 @@ class FormatTokenLexer {
FormatToken *getNextToken();
FormatToken *FormatTok;
- bool IsFirstToken;
+ bool getIsFirstToken() const { return Tokens.getFlag(0); }
+ void setIsFirstToken(bool Value) { Tokens.setFlag(0, Value); }
std::stack<LexerState> StateStack;
unsigned Column;
unsigned TrailingWhitespace;
@@ -128,21 +130,23 @@ class FormatTokenLexer {
llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator;
// Index (in 'Tokens') of the last token that starts a new line.
unsigned FirstInLineIndex;
- SmallVector<FormatToken *, 16> Tokens;
+ llvm::SmallVectorWithFlags<FormatToken *, 16, 3> Tokens;
llvm::SmallMapVector<IdentifierInfo *, TokenType, 8> Macros;
llvm::SmallPtrSet<IdentifierInfo *, 8> MacrosSkippedByRemoveParentheses,
TemplateNames, TypeNames, VariableTemplates;
- bool FormattingDisabled;
+ bool getFormattingDisabled() const { return Tokens.getFlag(1); }
+ void setFormattingDisabled(bool Value) { Tokens.setFlag(1, Value); }
llvm::Regex MacroBlockBeginRegex;
llvm::Regex MacroBlockEndRegex;
// The next line is a Verilog protected block that should not be split into
// tokens. Set at the 'pragma protect' line. Cleared at the next line.
- bool VerilogProtectedBlock;
+ bool getVerilogProtectedBlock() const { return Tokens.getFlag(2); }
+ void setVerilogProtectedBlock(bool Value) { Tokens.setFlag(2, Value); }
// Targets that may appear inside a C# attribute.
static const llvm::StringSet<> CSharpAttributeTargets;
diff --git a/clang/lib/Format/MacroCallReconstructor.cpp b/clang/lib/Format/MacroCallReconstructor.cpp
index 895d9f93dfce3..cde29d816d3aa 100644
--- a/clang/lib/Format/MacroCallReconstructor.cpp
+++ b/clang/lib/Format/MacroCallReconstructor.cpp
@@ -199,7 +199,7 @@ FormatToken *MacroCallReconstructor::getParentInResult(FormatToken *Parent) {
// If we use a different token than the parent in the expanded token stream
// as parent, mark it as a special parent, so the formatting code knows it
// needs to have its children formatted.
- Parent->MacroParent = true;
+ Parent->setMacroParent(true);
return Parent;
}
@@ -426,7 +426,7 @@ bool MacroCallReconstructor::processNextReconstructed() {
appendToken(Token);
prepareParent(Token, /*NewLine=*/true,
MacroCallStructure.back().Line->Level);
- Token->MacroParent = true;
+ Token->setMacroParent(true);
return false;
}
if (!MacroCallStructure.empty()) {
@@ -434,7 +434,7 @@ bool MacroCallReconstructor::processNextReconstructed() {
// Make new lines inside the next argument children of the comma token.
SpelledParentToReconstructedParent
[MacroCallStructure.back().Line->Tokens.back()->Tok] = Token;
- Token->MacroParent = true;
+ Token->setMacroParent(true);
appendToken(Token, MacroCallStructure.back().Line);
prepareParent(Token, /*NewLine=*/true,
MacroCallStructure.back().Line->Level);
@@ -489,7 +489,7 @@ void MacroCallReconstructor::finalize() {
// Mark the previous line's last token as generated by a macro expansion
// so the formatting algorithm can take that into account.
- Last->Tok->MacroParent = true;
+ Last->Tok->setMacroParent(true);
Last = Last->Children.back()->Tokens.back().get();
}
diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp
index 29c583855e3f5..22f0af531d812 100644
--- a/clang/lib/Format/QualifierAlignmentFixer.cpp
+++ b/clang/lib/Format/QualifierAlignmentFixer.cpp
@@ -573,7 +573,9 @@ LeftRightQualifierAlignmentFixer::LeftRightQualifierAlignmentFixer(
const Environment &Env, const FormatStyle &Style,
const std::string &Qualifier,
const std::vector<tok::TokenKind> &QualifierTokens, bool RightAlign)
- : TokenAnalyzer(Env, Style), Qualifier(Qualifier), RightAlign(RightAlign),
+ : TokenAnalyzer(Env, Style), Qualifier(Qualifier),
+ QualifierTokens(
+ decltype(this->QualifierTokens)::withFlags(unsigned(RightAlign))),
ConfiguredQualifierTokens(QualifierTokens) {}
std::pair<tooling::Replacements, unsigned>
@@ -588,7 +590,7 @@ LeftRightQualifierAlignmentFixer::analyze(
}
void LeftRightQualifierAlignmentFixer::fixQualifierAlignment(
- SmallVectorImpl<AnnotatedLine *> &AnnotatedLines, FormatTokenLexer &Tokens,
+ ArrayRef<AnnotatedLine *> AnnotatedLines, FormatTokenLexer &Tokens,
tooling::Replacements &Fixes) {
const AdditionalKeywords &Keywords = Tokens.getKeywords();
const SourceManager &SourceMgr = Env.getSourceManager();
@@ -612,7 +614,7 @@ void LeftRightQualifierAlignmentFixer::fixQualifierAlignment(
break;
if (Tok->is(tok::comment))
continue;
- if (RightAlign) {
+ if (getRightAlign()) {
Tok = analyzeRight(SourceMgr, Keywords, Fixes, Tok, Qualifier,
QualifierToken);
} else {
diff --git a/clang/lib/Format/QualifierAlignmentFixer.h b/clang/lib/Format/QualifierAlignmentFixer.h
index 09fcd7b943e67..92090f2bae1a3 100644
--- a/clang/lib/Format/QualifierAlignmentFixer.h
+++ b/clang/lib/Format/QualifierAlignmentFixer.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_LIB_FORMAT_QUALIFIERALIGNMENTFIXER_H
#include "TokenAnalyzer.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
namespace format {
@@ -40,8 +41,9 @@ bool isConfiguredQualifierOrType(const FormatToken *Tok,
class LeftRightQualifierAlignmentFixer : public TokenAnalyzer {
std::string Qualifier;
- bool RightAlign;
- SmallVector<tok::TokenKind, 8> QualifierTokens;
+ bool getRightAlign() const { return QualifierTokens.getFlag(0); }
+ void setRightAlign(bool Value) { QualifierTokens.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<tok::TokenKind, 8> QualifierTokens;
std::vector<tok::TokenKind> ConfiguredQualifierTokens;
public:
@@ -58,7 +60,7 @@ class LeftRightQualifierAlignmentFixer : public TokenAnalyzer {
static tok::TokenKind getTokenFromQualifier(const std::string &Qualifier);
- void fixQualifierAlignment(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
+ void fixQualifierAlignment(ArrayRef<AnnotatedLine *> AnnotatedLines,
FormatTokenLexer &Tokens,
tooling::Replacements &Fixes);
diff --git a/clang/lib/Format/SortJavaScriptImports.cpp b/clang/lib/Format/SortJavaScriptImports.cpp
index a403a4fed664c..609479e06948a 100644
--- a/clang/lib/Format/SortJavaScriptImports.cpp
+++ b/clang/lib/Format/SortJavaScriptImports.cpp
@@ -22,6 +22,7 @@
#include "clang/Format/Format.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Debug.h"
#include <string>
@@ -66,9 +67,12 @@ struct JsImportedSymbol {
// This struct represents both exports and imports to build up the information
// required for sorting module references.
struct JsModuleReference {
- bool FormattingOff = false;
- bool IsExport = false;
- bool IsTypeOnly = false;
+ bool getFormattingOff() const { return Symbols.getFlag(0); }
+ void setFormattingOff(bool Value) { Symbols.setFlag(0, Value); }
+ bool getIsExport() const { return Symbols.getFlag(1); }
+ void setIsExport(bool Value) { Symbols.setFlag(1, Value); }
+ bool getIsTypeOnly() const { return Symbols.getFlag(2); }
+ void setIsTypeOnly(bool Value) { Symbols.setFlag(2, Value); }
// Module references are sorted into these categories, in order.
enum ReferenceCategory {
SIDE_EFFECT, // "import 'something';"
@@ -86,10 +90,11 @@ struct JsModuleReference {
// Default import from "import DefaultName from '...';".
StringRef DefaultImport;
// Symbols from `import {SymbolA, SymbolB, ...} from ...;`.
- SmallVector<JsImportedSymbol, 1> Symbols;
+ llvm::SmallVectorWithFlags<JsImportedSymbol, 1, 4> Symbols;
// Whether some symbols were merged into this one. Controls if the module
// reference needs re-formatting.
- bool SymbolsMerged = false;
+ bool getSymbolsMerged() const { return Symbols.getFlag(3); }
+ void setSymbolsMerged(bool Value) { Symbols.setFlag(3, Value); }
// The source location just after { and just before } in the import.
// Extracted eagerly to allow modification of Symbols later on.
SourceLocation SymbolsStart, SymbolsEnd;
@@ -99,8 +104,8 @@ struct JsModuleReference {
};
bool operator<(const JsModuleReference &LHS, const JsModuleReference &RHS) {
- if (LHS.IsExport != RHS.IsExport)
- return LHS.IsExport < RHS.IsExport;
+ if (LHS.getIsExport() != RHS.getIsExport())
+ return LHS.getIsExport() < RHS.getIsExport();
if (LHS.Category != RHS.Category)
return LHS.Category < RHS.Category;
if (LHS.Category == JsModuleReference::ReferenceCategory::SIDE_EFFECT ||
@@ -167,8 +172,8 @@ class JavaScriptImportSorter : public TokenAnalyzer {
ReferencesText += "\n";
// Separate imports groups with two line breaks, but keep all exports
// in a single group.
- if (!Reference.IsExport &&
- (Reference.IsExport != References[I + 1].IsExport ||
+ if (!Reference.getIsExport() &&
+ (Reference.getIsExport() != References[I + 1].getIsExport() ||
Reference.Category != References[I + 1].Category)) {
ReferencesText += "\n";
}
@@ -261,13 +266,13 @@ class JavaScriptImportSorter : public TokenAnalyzer {
const auto *Start = References.begin();
SmallVector<JsModuleReference, 16> ReferencesSorted;
while (Start != References.end()) {
- while (Start != References.end() && Start->FormattingOff) {
+ while (Start != References.end() && Start->getFormattingOff()) {
// Skip over all imports w/ disabled formatting.
ReferencesSorted.push_back(*Start);
++Start;
}
SmallVector<JsModuleReference, 16> SortChunk;
- while (Start != References.end() && !Start->FormattingOff) {
+ while (Start != References.end() && !Start->getFormattingOff()) {
// Skip over all imports w/ disabled formatting.
SortChunk.push_back(*Start);
++Start;
@@ -301,8 +306,8 @@ class JavaScriptImportSorter : public TokenAnalyzer {
// mismatching
if (Reference->Category == JsModuleReference::SIDE_EFFECT ||
PreviousReference->Category == JsModuleReference::SIDE_EFFECT ||
- Reference->IsExport != PreviousReference->IsExport ||
- Reference->IsTypeOnly != PreviousReference->IsTypeOnly ||
+ Reference->getIsExport() != PreviousReference->getIsExport() ||
+ Reference->getIsTypeOnly() != PreviousReference->getIsTypeOnly() ||
!PreviousReference->Prefix.empty() || !Reference->Prefix.empty() ||
!PreviousReference->DefaultImport.empty() ||
!Reference->DefaultImport.empty() || Reference->Symbols.empty() ||
@@ -312,8 +317,8 @@ class JavaScriptImportSorter : public TokenAnalyzer {
continue;
}
// Merge symbols from identical imports.
- PreviousReference->Symbols.append(Reference->Symbols);
- PreviousReference->SymbolsMerged = true;
+ llvm::append_range(PreviousReference->Symbols, Reference->Symbols);
+ PreviousReference->setSymbolsMerged(true);
// Remove the merged import.
Reference = References.erase(Reference);
}
@@ -321,19 +326,22 @@ class JavaScriptImportSorter : public TokenAnalyzer {
// Appends ``Reference`` to ``Buffer``.
void appendReference(std::string &Buffer, JsModuleReference &Reference) {
- if (Reference.FormattingOff) {
+ if (Reference.getFormattingOff()) {
Buffer +=
getSourceText(Reference.Range.getBegin(), Reference.Range.getEnd());
return;
}
// Sort the individual symbols within the import.
// E.g. `import {b, a} from 'x';` -> `import {a, b} from 'x';`
- SmallVector<JsImportedSymbol, 1> Symbols = Reference.Symbols;
+ SmallVector<JsImportedSymbol, 1> Symbols(Reference.Symbols.begin(),
+ Reference.Symbols.end());
stable_sort(Symbols,
[&](const JsImportedSymbol &LHS, const JsImportedSymbol &RHS) {
return LHS.Symbol.compare_insensitive(RHS.Symbol) < 0;
});
- if (!Reference.SymbolsMerged && Symbols == Reference.Symbols) {
+ if (!Reference.getSymbolsMerged() &&
+ llvm::ArrayRef<JsImportedSymbol>(Symbols) ==
+ llvm::ArrayRef<JsImportedSymbol>(Reference.Symbols)) {
// Symbols didn't change, just emit the entire module reference.
StringRef ReferenceStmt = getSourceText(Reference.Range);
Buffer += ReferenceStmt;
@@ -401,7 +409,7 @@ class JavaScriptImportSorter : public TokenAnalyzer {
continue;
}
JsModuleReference Reference;
- Reference.FormattingOff = FormattingOff;
+ Reference.setFormattingOff(FormattingOff);
Reference.Range.setBegin(Start);
// References w/o a URL, e.g. export {A}, groups with RELATIVE.
Reference.Category = JsModuleReference::ReferenceCategory::RELATIVE;
@@ -415,8 +423,8 @@ class JavaScriptImportSorter : public TokenAnalyzer {
Reference.Range.setEnd(LineEnd->Tok.getEndLoc());
LLVM_DEBUG({
llvm::dbgs() << "JsModuleReference: {"
- << "formatting_off: " << Reference.FormattingOff
- << ", is_export: " << Reference.IsExport
+ << "formatting_off: " << Reference.getFormattingOff()
+ << ", is_export: " << Reference.getIsExport()
<< ", cat: " << Reference.Category
<< ", url: " << Reference.URL
<< ", prefix: " << Reference.Prefix;
@@ -441,10 +449,10 @@ class JavaScriptImportSorter : public TokenAnalyzer {
JsModuleReference &Reference) {
if (!Current || Current->isNoneOf(Keywords.kw_import, tok::kw_export))
return false;
- Reference.IsExport = Current->is(tok::kw_export);
+ Reference.setIsExport(Current->is(tok::kw_export));
nextToken();
- if (Current->isStringLiteral() && !Reference.IsExport) {
+ if (Current->isStringLiteral() && !Reference.getIsExport()) {
// "import 'side-effect';"
Reference.Category = JsModuleReference::ReferenceCategory::SIDE_EFFECT;
Reference.URL =
@@ -487,7 +495,7 @@ class JavaScriptImportSorter : public TokenAnalyzer {
// * as prefix from '...';
if (Current->is(Keywords.kw_type) && Current->Next &&
Current->Next->is(tok::star)) {
- Reference.IsTypeOnly = true;
+ Reference.setIsTypeOnly(true);
nextToken();
}
if (Current->isNot(tok::star))
@@ -507,12 +515,12 @@ class JavaScriptImportSorter : public TokenAnalyzer {
JsModuleReference &Reference) {
if (Current->is(Keywords.kw_type) && Current->Next &&
Current->Next->isOneOf(tok::identifier, tok::l_brace)) {
- Reference.IsTypeOnly = true;
+ Reference.setIsTypeOnly(true);
nextToken();
}
// eat a potential "import X, " prefix.
- if (!Reference.IsExport && Current->is(tok::identifier)) {
+ if (!Reference.getIsExport() && Current->is(tok::identifier)) {
Reference.DefaultImport = Current->TokenText;
nextToken();
if (Current->is(Keywords.kw_from))
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 382f15081ad74..2a67971468f7b 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -16,6 +16,7 @@
#include "FormatToken.h"
#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "format-token-annotator"
@@ -125,10 +126,12 @@ class AnnotatingParser {
public:
AnnotatingParser(const FormatStyle &Style, AnnotatedLine &Line,
const AdditionalKeywords &Keywords,
- SmallVector<ScopeType> &Scopes)
- : Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
- IsCpp(Style.isCpp()), LangOpts(getFormattingLangOpts(Style)),
- Keywords(Keywords), Scopes(Scopes), TemplateDeclarationDepth(0) {
+ llvm::SmallVectorWithFlagsImpl<ScopeType> &Scopes)
+ : Contexts(decltype(this->Contexts)::withFlags(
+ unsigned(bool(Style.isCpp())) << 1)),
+ Style(Style), Line(Line), CurrentToken(Line.First),
+ LangOpts(getFormattingLangOpts(Style)), Keywords(Keywords),
+ Scopes(Scopes), TemplateDeclarationDepth(0) {
Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
resetTokenMetadata();
}
@@ -696,13 +699,13 @@ class AnnotatingParser {
// In C++, this can happen either in array of templates (foo<int>[10])
// or when array is a nested template type (unique_ptr<type1<type2>[]>).
bool CppArrayTemplates =
- IsCpp && Parent && Parent->is(TT_TemplateCloser) &&
+ getIsCpp() && Parent && Parent->is(TT_TemplateCloser) &&
(Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
Contexts.back().ContextType == Context::TemplateArgument);
const bool IsInnerSquare = Contexts.back().InCpp11AttributeSpecifier;
const bool IsCpp11AttributeSpecifier =
- isCppAttribute(IsCpp, *Left) || IsInnerSquare;
+ isCppAttribute(getIsCpp(), *Left) || IsInnerSquare;
// Treat C# Attributes [STAThread] much like C++ attributes [[...]].
bool IsCSharpAttributeSpecifier =
@@ -710,11 +713,12 @@ class AnnotatingParser {
Contexts.back().InCSharpAttributeSpecifier;
bool InsideInlineASM = Line.startsWith(tok::kw_asm);
- bool IsCppStructuredBinding = Left->isCppStructuredBinding(IsCpp);
+ bool IsCppStructuredBinding = Left->isCppStructuredBinding(getIsCpp());
bool StartsObjCMethodExpr =
!IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
- IsCpp && !IsCpp11AttributeSpecifier && !IsCSharpAttributeSpecifier &&
- Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
+ getIsCpp() && !IsCpp11AttributeSpecifier &&
+ !IsCSharpAttributeSpecifier && Contexts.back().CanBeExpression &&
+ Left->isNot(TT_LambdaLSquare) &&
CurrentToken->isNoneOf(tok::l_brace, tok::r_square) &&
// Do not consider '[' after a comma inside a braced initializer the
// start of an ObjC method expression. In braced initializer lists,
@@ -749,7 +753,7 @@ class AnnotatingParser {
Contexts.back().ContextKind == tok::l_brace &&
Parent->isOneOf(tok::l_brace, tok::comma)) {
Left->setType(TT_JsComputedPropertyName);
- } else if (IsCpp && Contexts.back().ContextKind == tok::l_brace &&
+ } else if (getIsCpp() && Contexts.back().ContextKind == tok::l_brace &&
Parent && Parent->isOneOf(tok::l_brace, tok::comma)) {
Left->setType(TT_DesignatedInitializerLSquare);
} else if (IsCSharpAttributeSpecifier) {
@@ -1239,7 +1243,7 @@ class AnnotatingParser {
if (Previous->is(TT_JsTypeOptionalQuestion))
Previous = Previous->getPreviousNonComment();
if ((CurrentToken->is(tok::colon) && !Style.isTableGen() &&
- (!Contexts.back().ColonIsDictLiteral || !IsCpp)) ||
+ (!Contexts.back().ColonIsDictLiteral || !getIsCpp())) ||
Style.isProto()) {
OpeningBrace.setType(TT_DictLiteral);
Scopes.back() = getScopeType(OpeningBrace);
@@ -1329,7 +1333,7 @@ class AnnotatingParser {
}
bool consumeToken() {
- if (IsCpp) {
+ if (getIsCpp()) {
const auto *Prev = CurrentToken->getPreviousNonComment();
if (Prev && Prev->is(TT_AttributeRSquare) &&
CurrentToken->isOneOf(tok::kw_if, tok::kw_switch, tok::kw_case,
@@ -1518,7 +1522,7 @@ class AnnotatingParser {
if (CurrentToken && CurrentToken->is(Keywords.kw_await))
next();
}
- if (IsCpp && CurrentToken && CurrentToken->is(tok::kw_co_await))
+ if (getIsCpp() && CurrentToken && CurrentToken->is(tok::kw_co_await))
next();
Contexts.back().ColonIsForRangeExpr = true;
if (!CurrentToken || CurrentToken->isNot(tok::l_paren))
@@ -1607,7 +1611,7 @@ class AnnotatingParser {
return false;
break;
case tok::l_brace:
- if (IsCpp) {
+ if (getIsCpp()) {
if (Tok->is(TT_RequiresExpressionLBrace))
Line.Type = LT_RequiresExpression;
} else if (Style.isTextProto()) {
@@ -1663,7 +1667,7 @@ class AnnotatingParser {
if (Style.isProto())
break;
// Handle C++ user-defined conversion function.
- if (IsCpp && CurrentToken) {
+ if (getIsCpp() && CurrentToken) {
const auto *Info = CurrentToken->Tok.getIdentifierInfo();
// What follows Tok is an identifier or a non-operator keyword.
if (Info && !(CurrentToken->isPlacementOperator() ||
@@ -1806,7 +1810,7 @@ class AnnotatingParser {
Keywords.kw___has_include_next)) {
parseHasInclude();
}
- if (IsCpp) {
+ if (getIsCpp()) {
if (Next && Next->is(tok::l_paren) && Prev &&
Prev->isOneOf(tok::kw___cdecl, tok::kw___stdcall,
tok::kw___fastcall, tok::kw___thiscall,
@@ -1819,7 +1823,7 @@ class AnnotatingParser {
Tok->setType(TT_CSharpGenericTypeConstraint);
parseCSharpGenericTypeConstraint();
if (!Prev)
- Line.IsContinuation = true;
+ Line.setIsContinuation(true);
}
} else if (Style.isTableGen()) {
if (Tok->is(Keywords.kw_assert)) {
@@ -2456,13 +2460,13 @@ class AnnotatingParser {
// having multiple variable declarations.
Contexts.back().FirstStartOfName = nullptr;
} else if (Current.isOneOf(tok::kw_auto, tok::kw___auto_type)) {
- AutoFound = true;
+ setAutoFound(true);
} else if (Current.is(tok::arrow) && Style.isJava()) {
Current.setType(TT_LambdaArrow);
} else if (Current.is(tok::arrow) && Style.isVerilog()) {
// The implication operator.
Current.setType(TT_BinaryOperator);
- } else if (Current.is(tok::arrow) && AutoFound &&
+ } else if (Current.is(tok::arrow) && getAutoFound() &&
Line.MightBeFunctionDecl && Current.NestingLevel == 0 &&
Current.Previous->isNoneOf(tok::kw_operator, tok::identifier)) {
// not auto operator->() -> xxx;
@@ -2502,7 +2506,7 @@ class AnnotatingParser {
Current.setType(TT_Unknown);
} else {
Current.setType(TT_ConditionalExpr);
- if (IsCpp)
+ if (getIsCpp())
Contexts.back().IsExpression = true;
}
} else if (Current.isBinaryOperator() &&
@@ -2740,7 +2744,7 @@ class AnnotatingParser {
/// Determine whether '(' is starting a C++ cast.
bool lParenStartsCppCast(const FormatToken &Tok) {
// C-style casts are only used in C++.
- if (!IsCpp)
+ if (!getIsCpp())
return false;
FormatToken *LeftOfParens = Tok.getPreviousNonComment();
@@ -2766,7 +2770,7 @@ class AnnotatingParser {
return false;
// C-style casts are only used in C++, C# and Java.
- if (!IsCpp && !Style.isCSharp() && !Style.isJava())
+ if (!getIsCpp() && !Style.isCSharp() && !Style.isJava())
return false;
const auto *LParen = Tok.MatchingParen;
@@ -2850,7 +2854,7 @@ class AnnotatingParser {
if (AfterRParen->isOneOf(tok::kw_noexcept, tok::kw_volatile, tok::kw_const,
tok::kw_requires, tok::kw_throw, tok::arrow,
Keywords.kw_override, Keywords.kw_final) ||
- isCppAttribute(IsCpp, *AfterRParen)) {
+ isCppAttribute(getIsCpp(), *AfterRParen)) {
return false;
}
@@ -3223,17 +3227,19 @@ class AnnotatingParser {
return TT_UnaryOperator;
}
- SmallVector<Context, 8> Contexts;
+ llvm::SmallVectorWithFlags<Context, 8, 2> Contexts;
const FormatStyle &Style;
AnnotatedLine &Line;
FormatToken *CurrentToken;
- bool AutoFound;
- bool IsCpp;
+ bool getAutoFound() const { return Contexts.getFlag(0); }
+ void setAutoFound(bool Value) { Contexts.setFlag(0, Value); }
+ bool getIsCpp() const { return Contexts.getFlag(1); }
+ void setIsCpp(bool Value) { Contexts.setFlag(1, Value); }
LangOptions LangOpts;
const AdditionalKeywords &Keywords;
- SmallVector<ScopeType> &Scopes;
+ llvm::SmallVectorWithFlagsImpl<ScopeType> &Scopes;
// Set of "<" tokens that do not open a template parameter list. If parseAngle
// determines that a specific token can't be a template opener, it will make
@@ -3462,7 +3468,7 @@ class ExpressionParser {
// unexpanded macro call. The line within the macro call contains
// the parenthesis and commas, and we will not find operators within
// that structure.
- if (Start->MacroParent)
+ if (Start->getMacroParent())
return;
Start->FakeLParens.push_back(Precedence);
@@ -3662,7 +3668,7 @@ class ExpressionParser {
} // end anonymous namespace
void TokenAnnotator::setCommentLineLevels(
- SmallVectorImpl<AnnotatedLine *> &Lines) const {
+ ArrayRef<AnnotatedLine *> Lines) const {
const AnnotatedLine *NextNonCommentLine = nullptr;
for (AnnotatedLine *Line : reverse(Lines)) {
assert(Line->First);
@@ -3876,7 +3882,7 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) {
ExpressionParser ExprParser(Style, Keywords, Line);
ExprParser.parse();
- if (IsCpp) {
+ if (getIsCpp()) {
FormatToken *OpeningParen = nullptr;
auto *Tok = getFunctionName(Line, OpeningParen);
if (Tok && ((!ScopeStack.empty() && ScopeStack.back() == ST_Class) ||
@@ -4190,7 +4196,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
}
}
- if (IsCpp) {
+ if (getIsCpp()) {
if ((LineIsFunctionDeclaration ||
(FirstNonComment && FirstNonComment->is(TT_CtorDtorDeclName))) &&
Line.endsWith(tok::semi, tok::r_brace)) {
@@ -4209,11 +4215,11 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
mustBreakAfterAttributes(*AfterLastAttribute, Style)) {
AfterLastAttribute->MustBreakBefore = true;
if (LineIsFunctionDeclaration)
- Line.ReturnTypeWrapped = true;
+ Line.setReturnTypeWrapped(true);
}
if (!LineIsFunctionDeclaration) {
- Line.ReturnTypeWrapped = false;
+ Line.setReturnTypeWrapped(false);
// Annotate */&/&& in `operator` function calls as binary operators.
for (const auto *Tok = FirstNonComment; Tok; Tok = Tok->Next) {
if (Tok->isNot(tok::kw_operator))
@@ -4265,7 +4271,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
ReturnTypeStart->isNoneOf(TT_FunctionDeclarationName,
TT_CtorDtorDeclName, tok::tilde)) {
ReturnTypeStart->MustBreakBefore = true;
- Line.ReturnTypeWrapped = true;
+ Line.setReturnTypeWrapped(true);
}
}
@@ -5206,7 +5212,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return Right.hasWhitespaceBefore();
const bool IsVerilog = Style.isVerilog();
- assert(!IsVerilog || !IsCpp);
+ assert(!IsVerilog || !getIsCpp());
// Never ever merge two words.
if (Keywords.isWordLike(Right, IsVerilog) &&
@@ -5232,7 +5238,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
const auto *BeforeLeft = Left.Previous;
- if (IsCpp) {
+ if (getIsCpp()) {
if (Left.is(TT_OverloadedOperator) &&
Right.isOneOf(TT_TemplateOpener, TT_TemplateCloser)) {
return true;
@@ -5663,7 +5669,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
if (Left.is(tok::comma) && Right.isNot(TT_OverloadedOperatorLParen) &&
// In an unexpanded macro call we only find the parentheses and commas
// in a line; the commas and closing parenthesis do not require a space.
- (Left.Children.empty() || !Left.MacroParent)) {
+ (Left.Children.empty() || !Left.getMacroParent())) {
return true;
}
if (Right.is(tok::comma))
@@ -5986,7 +5992,7 @@ bool TokenAnnotator::mustBreakBefore(AnnotatedLine &Line,
if (!Keywords.isVerilogBegin(Right) && Keywords.isVerilogEndOfLabel(Left))
return true;
} else if (Style.BreakAdjacentStringLiterals &&
- (IsCpp || Style.isProto() || Style.isTableGen())) {
+ (getIsCpp() || Style.isProto() || Style.isTableGen())) {
if (Left.isStringLiteral() && Right.isStringLiteral())
return true;
}
@@ -6346,7 +6352,7 @@ bool TokenAnnotator::mustBreakBefore(AnnotatedLine &Line,
if (Style.BreakAfterAttributes == FormatStyle::ABS_LeaveAll &&
Left.is(TT_AttributeRSquare) && Right.NewlinesBefore > 0) {
- Line.ReturnTypeWrapped = true;
+ Line.setReturnTypeWrapped(true);
return true;
}
@@ -6777,7 +6783,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) const {
llvm::errs() << "AnnotatedTokens(L=" << Line.Level << ", P=" << Line.PPLevel
- << ", T=" << Line.Type << ", C=" << Line.IsContinuation
+ << ", T=" << Line.Type << ", C=" << Line.getIsContinuation()
<< "):\n";
const FormatToken *Tok = Line.First;
while (Tok) {
diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h
index c909c39e92ea3..8045a1c688db9 100644
--- a/clang/lib/Format/TokenAnnotator.h
+++ b/clang/lib/Format/TokenAnnotator.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_LIB_FORMAT_TOKENANNOTATOR_H
#include "UnwrappedLineParser.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
namespace format {
@@ -51,8 +52,10 @@ enum ScopeType {
class AnnotatedLine {
public:
AnnotatedLine(const UnwrappedLine &Line)
- : First(Line.Tokens.front().Tok), Type(LT_Other), Level(Line.Level),
- PPLevel(Line.PPLevel),
+ : First(Line.Tokens.front().Tok),
+ Children(decltype(this->Children)::withFlags(
+ unsigned(bool(Line.IsContinuation)) << 1)),
+ Type(LT_Other), Level(Line.Level), PPLevel(Line.PPLevel),
MatchingOpeningBlockLineIndex(Line.MatchingOpeningBlockLineIndex),
MatchingClosingBlockLineIndex(Line.MatchingClosingBlockLineIndex),
InPPDirective(Line.InPPDirective),
@@ -62,7 +65,6 @@ class AnnotatedLine {
MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
IsMultiVariableDeclStmt(false), Affected(false),
LeadingEmptyLinesAffected(false), ChildrenAffected(false),
- ReturnTypeWrapped(false), IsContinuation(Line.IsContinuation),
FirstStartColumn(Line.FirstStartColumn) {
assert(!Line.Tokens.empty());
@@ -73,7 +75,7 @@ class AnnotatedLine {
FormatToken *Current = First;
addChildren(Line.Tokens.front(), Current);
for (const UnwrappedLineNode &Node : llvm::drop_begin(Line.Tokens)) {
- if (Node.Tok->MacroParent)
+ if (Node.Tok->getMacroParent())
ContainsMacroCall = true;
Current->Next = Node.Tok;
Node.Tok->Previous = Current;
@@ -170,7 +172,7 @@ class AnnotatedLine {
FormatToken *First;
FormatToken *Last;
- SmallVector<AnnotatedLine *, 0> Children;
+ llvm::SmallVectorWithFlags<AnnotatedLine *, 0, 2> Children;
LineType Type;
unsigned Level;
@@ -203,11 +205,19 @@ class AnnotatedLine {
bool ChildrenAffected;
/// \c True if breaking after last attribute group in function return type.
- bool ReturnTypeWrapped;
+ bool getReturnTypeWrapped() const { return Children.getFlag(0); }
+ bool setReturnTypeWrapped(bool Value) {
+ Children.setFlag(0, Value);
+ return Value;
+ }
/// \c True if this line should be indented by ContinuationIndent in addition
/// to the normal indention level.
- bool IsContinuation;
+ bool getIsContinuation() const { return Children.getFlag(1); }
+ bool setIsContinuation(bool Value) {
+ Children.setFlag(1, Value);
+ return Value;
+ }
unsigned FirstStartColumn;
@@ -222,13 +232,14 @@ class AnnotatedLine {
class TokenAnnotator {
public:
TokenAnnotator(const FormatStyle &Style, const AdditionalKeywords &Keywords)
- : Style(Style), IsCpp(Style.isCpp()),
- LangOpts(getFormattingLangOpts(Style)), Keywords(Keywords) {}
+ : Style(Style), LangOpts(getFormattingLangOpts(Style)),
+ Keywords(Keywords), Scopes(decltype(Scopes)::withFlags(Style.isCpp())) {
+ }
/// Adapts the indent levels of comment lines to the indent of the
/// subsequent line.
// FIXME: Can/should this be done in the UnwrappedLineParser?
- void setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines) const;
+ void setCommentLineLevels(ArrayRef<AnnotatedLine *> Lines) const;
void annotate(AnnotatedLine &Line);
void calculateFormattingInformation(AnnotatedLine &Line) const;
@@ -272,12 +283,13 @@ class TokenAnnotator {
const FormatStyle &Style;
- bool IsCpp;
+ bool getIsCpp() const { return Scopes.getFlag(0); }
LangOptions LangOpts;
const AdditionalKeywords &Keywords;
- SmallVector<ScopeType> Scopes, MacroBodyScopes;
+ llvm::SmallVectorWithFlags<ScopeType> Scopes;
+ llvm::SmallVectorWithFlags<ScopeType> MacroBodyScopes;
};
} // end namespace format
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index e42a2083f7268..8c5960606254c 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -90,7 +90,7 @@ class LevelIndentTracker {
}
if (static_cast<int>(Indent) + Offset >= 0)
Indent += Offset;
- if (Line.IsContinuation)
+ if (Line.getIsContinuation())
Indent = Line.Level * Style.IndentWidth + Style.ContinuationIndentWidth;
}
@@ -100,7 +100,7 @@ class LevelIndentTracker {
/// level to the same indent.
/// Note that \c nextLine must have been called before this method.
void adjustToUnmodifiedLine(const AnnotatedLine &Line) {
- if (Line.InPPDirective || Line.IsContinuation)
+ if (Line.InPPDirective || Line.getIsContinuation())
return;
assert(Line.Level < IndentForLevel.size());
if (Line.First->is(tok::comment) && IndentForLevel[Line.Level] != -1)
@@ -1216,13 +1216,14 @@ class LineFormatter {
const FormatToken *LBrace = State.NextToken->getPreviousNonComment();
bool HasLBrace = LBrace && LBrace->is(tok::l_brace) && LBrace->is(BK_Block);
FormatToken &Previous = *State.NextToken->Previous;
- if (Previous.Children.empty() || (!HasLBrace && !LBrace->MacroParent)) {
+ if (Previous.Children.empty() ||
+ (!HasLBrace && !LBrace->getMacroParent())) {
// The previous token does not open a block. Nothing to do. We don't
// assert so that we can simply call this function for all tokens.
return true;
}
- if (NewLine || Previous.MacroParent) {
+ if (NewLine || Previous.getMacroParent()) {
const ParenState &P = State.Stack.back();
int AdditionalIndent =
@@ -1430,7 +1431,7 @@ class OptimizingLineFormatter : public LineFormatter {
// Cut off the analysis of certain solutions if the analysis gets too
// complex. See description of IgnoreStackForComparison.
if (Count > 50'000)
- Node->State.IgnoreStackForComparison = true;
+ Node->State.setIgnoreStackForComparison(true);
if (!Seen.insert(&Node->State).second) {
// State already examined with lower penalty.
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 901335950b9fa..2631593a45f73 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -123,7 +123,7 @@ class ScopedLineState {
Parser.CurrentLines->truncate(OriginalNumLines);
Parser.Line = std::move(PreBlockLine);
if (Parser.CurrentLines == &Parser.PreprocessorDirectives)
- Parser.PP.AtEndOfPPLine = true;
+ Parser.PP.setAtEndOfPPLine(true);
Parser.CurrentLines = OriginalLines;
}
@@ -166,9 +166,11 @@ UnwrappedLineParser::UnwrappedLineParser(
llvm::SpecificBumpPtrAllocator<FormatToken> &Allocator,
IdentifierTable &IdentTable)
: Line(new UnwrappedLine), CurrentLines(&Lines), Style(Style),
- IsCpp(Style.isCpp()), LangOpts(getFormattingLangOpts(Style)),
- Keywords(Keywords), CommentPragmasRegex(Style.CommentPragmas),
- Tokens(nullptr), Callback(Callback), AllTokens(Tokens),
+ LangOpts(getFormattingLangOpts(Style)), Keywords(Keywords),
+ CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
+ Callback(Callback), AllTokens(Tokens),
+ NestedLambdas(decltype(this->NestedLambdas)::withFlags(
+ unsigned(bool(Style.isCpp())) << 1)),
PP(getIncludeGuardState(Style.IndentPPDirectives)),
FirstStartColumn(FirstStartColumn),
Macros(Style.Macros, SourceMgr, Style, Allocator, IdentTable) {}
@@ -181,8 +183,8 @@ void UnwrappedLineParser::reset() {
Line.reset(new UnwrappedLine);
CommentsBeforeNextToken.clear();
FormatTok = nullptr;
- PP.AtEndOfPPLine = false;
- IsDecltypeAutoFunction = false;
+ PP.setAtEndOfPPLine(false);
+ setIsDecltypeAutoFunction(false);
PreprocessorDirectives.clear();
CurrentLines = &Lines;
DeclarationScopeStack.clear();
@@ -197,7 +199,7 @@ void UnwrappedLineParser::reset() {
CurrentExpandedLines.clear();
ExpandedLines.clear();
Unexpanded.clear();
- InExpansion = false;
+ setInExpansion(false);
Reconstruct.reset();
}
@@ -583,8 +585,8 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
Keywords.kw_as));
ProbablyBracedList =
ProbablyBracedList ||
- (IsCpp && (PrevTok->Tok.isLiteral() ||
- NextTok->isOneOf(tok::l_paren, tok::arrow)));
+ (getIsCpp() && (PrevTok->Tok.isLiteral() ||
+ NextTok->isOneOf(tok::l_paren, tok::arrow)));
// If there is a comma, or right paren after the closing brace, we
// assume this is a braced initializer list.
@@ -624,7 +626,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
}
// Cpp macro definition body that is a nonempty braced list or block:
- if (IsCpp && Line->InMacroBody && PrevTok != FormatTok &&
+ if (getIsCpp() && Line->InMacroBody && PrevTok != FormatTok &&
!FormatTok->Previous && NextTok->is(tok::eof) &&
// A statement can end with only `;` (simple statement), a block
// closing brace (compound statement), or `:` (label statement).
@@ -1377,7 +1379,7 @@ static bool isC78ParameterDecl(const FormatToken *Tok, const FormatToken *Next,
}
bool UnwrappedLineParser::parseModuleDecl() {
- assert(IsCpp);
+ assert(getIsCpp());
assert(FormatTok->is(Keywords.kw_module));
if (Style.Language == FormatStyle::LK_C ||
@@ -1400,7 +1402,7 @@ bool UnwrappedLineParser::parseModuleDecl() {
}
bool UnwrappedLineParser::parseImportDecl() {
- assert(IsCpp);
+ assert(getIsCpp());
assert(FormatTok->is(Keywords.kw_import) && "'import' expected");
if (Style.Language == FormatStyle::LK_C ||
@@ -1493,7 +1495,7 @@ void UnwrappedLineParser::parseStructuralElement(
return;
}
- if (IsCpp) {
+ if (getIsCpp()) {
while (FormatTok->is(tok::l_square) && handleCppAttributes()) {
}
} else if (Style.isVerilog()) {
@@ -1702,7 +1704,7 @@ void UnwrappedLineParser::parseStructuralElement(
}
break;
case tok::kw_export:
- if (IsCpp) {
+ if (getIsCpp()) {
nextToken();
if (FormatTok->is(tok::kw_namespace)) {
parseNamespace();
@@ -1745,7 +1747,7 @@ void UnwrappedLineParser::parseStructuralElement(
return;
}
if (FormatTok->is(Keywords.kw_import)) {
- if (IsCpp && parseImportDecl())
+ if (getIsCpp() && parseImportDecl())
return;
if (Style.isJavaScript()) {
parseJavaScriptEs6ImportExport();
@@ -1768,7 +1770,7 @@ void UnwrappedLineParser::parseStructuralElement(
return;
}
}
- if (IsCpp) {
+ if (getIsCpp()) {
if (FormatTok->is(Keywords.kw_module) && parseModuleDecl())
return;
if (FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals,
@@ -1881,7 +1883,7 @@ void UnwrappedLineParser::parseStructuralElement(
}
break;
case tok::kw_requires: {
- if (IsCpp) {
+ if (getIsCpp()) {
bool ParsedClause = parseRequires(SeenEqual);
if (ParsedClause)
return;
@@ -1903,7 +1905,7 @@ void UnwrappedLineParser::parseStructuralElement(
if (!parseEnum())
break;
// This only applies to C++ and Verilog.
- if (!IsCpp && !Style.isVerilog()) {
+ if (!getIsCpp() && !Style.isVerilog()) {
addUnwrappedLine();
return;
}
@@ -1978,7 +1980,7 @@ void UnwrappedLineParser::parseStructuralElement(
parseParens();
// Break the unwrapped line if a K&R C function definition has a parameter
// declaration.
- if (OpeningBrace || !IsCpp || !Previous || eof())
+ if (OpeningBrace || !getIsCpp() || !Previous || eof())
break;
if (isC78ParameterDecl(FormatTok,
Tokens->peekNextToken(/*SkipComment=*/true),
@@ -2022,7 +2024,7 @@ void UnwrappedLineParser::parseStructuralElement(
if (InRequiresExpression)
FormatTok->setFinalizedType(TT_BracedListLBrace);
if (!tryToParsePropertyAccessor() && !tryToParseBracedList()) {
- IsDecltypeAutoFunction = Line->SeenDecltypeAuto;
+ setIsDecltypeAutoFunction(Line->SeenDecltypeAuto);
// A block outside of parentheses must be the last part of a
// structural element.
// FIXME: Figure out cases where this is not true, and add projections
@@ -2041,7 +2043,7 @@ void UnwrappedLineParser::parseStructuralElement(
if (!Previous || Previous->isNot(TT_TypeDeclarationParen))
FormatTok->setFinalizedType(TT_FunctionLBrace);
parseBlock();
- IsDecltypeAutoFunction = false;
+ setIsDecltypeAutoFunction(false);
addUnwrappedLine();
return;
}
@@ -2116,13 +2118,13 @@ void UnwrappedLineParser::parseStructuralElement(
}
}
- if (!IsCpp && FormatTok->is(Keywords.kw_interface)) {
+ if (!getIsCpp() && FormatTok->is(Keywords.kw_interface)) {
if (parseStructLike())
return;
break;
}
- if (IsCpp && FormatTok->is(TT_StatementMacro)) {
+ if (getIsCpp() && FormatTok->is(TT_StatementMacro)) {
parseStatementMacro();
return;
}
@@ -2374,7 +2376,7 @@ bool UnwrappedLineParser::tryToParsePropertyAccessor() {
bool UnwrappedLineParser::tryToParseLambda() {
assert(FormatTok->is(tok::l_square));
- if (!IsCpp) {
+ if (!getIsCpp()) {
nextToken();
return false;
}
@@ -2516,7 +2518,7 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
return false;
}
}
- if (LeftSquare->isCppStructuredBinding(IsCpp))
+ if (LeftSquare->isCppStructuredBinding(getIsCpp()))
return false;
if (FormatTok->is(tok::l_square) || tok::isLiteral(FormatTok->Tok.getKind()))
return false;
@@ -2757,7 +2759,7 @@ bool UnwrappedLineParser::parseParens(TokenType StarAndAmpTokenType,
}
const bool ReturnParens =
Style.RemoveParentheses == FormatStyle::RPS_ReturnStatement &&
- ((NestedLambdas.empty() && !IsDecltypeAutoFunction) ||
+ ((NestedLambdas.empty() && !getIsDecltypeAutoFunction()) ||
(!NestedLambdas.empty() && !NestedLambdas.back())) &&
Prev->isOneOf(tok::kw_return, tok::kw_co_return) &&
FormatTok->is(tok::semi);
@@ -3434,7 +3436,7 @@ void UnwrappedLineParser::parseForOrWhileLoop(bool HasParens) {
// JS' for await ( ...
if (Style.isJavaScript() && FormatTok->is(Keywords.kw_await))
nextToken();
- if (IsCpp && FormatTok->is(tok::kw_co_await))
+ if (getIsCpp() && FormatTok->is(tok::kw_co_await))
nextToken();
if (HasParens && FormatTok->is(tok::l_paren)) {
// The type is only set for Verilog basically because we were afraid to
@@ -3944,7 +3946,7 @@ bool UnwrappedLineParser::parseEnum() {
if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))
return false;
- if (IsCpp) {
+ if (getIsCpp()) {
// Eat up enum class ...
if (FormatTok->isOneOf(tok::kw_class, tok::kw_struct))
nextToken();
@@ -3975,7 +3977,7 @@ bool UnwrappedLineParser::parseEnum() {
nextToken();
// If there are two identifiers in a row, this is likely an elaborate
// return type. In Java, this can be "implements", etc.
- if (IsCpp && FormatTok->is(tok::identifier))
+ if (getIsCpp() && FormatTok->is(tok::identifier))
return false;
}
}
@@ -4783,7 +4785,7 @@ void UnwrappedLineParser::addUnwrappedLine(LineLevel AdjustLevel) {
// If the current line was expanded from a macro call, we use it to
// reconstruct an unwrapped line from the structure of the expanded unwrapped
// line and the unexpanded token stream.
- if (!parsingPPDirective() && !InExpansion && containsExpansion(*Line)) {
+ if (!parsingPPDirective() && !getInExpansion() && containsExpansion(*Line)) {
if (!Reconstruct)
Reconstruct.emplace(Line->Level, Unexpanded);
Reconstruct->addLine(*Line);
@@ -5155,11 +5157,11 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
// call with its expansion.
auto PreCall = std::move(Line);
Line.reset(new UnwrappedLine);
- bool OldInExpansion = InExpansion;
- InExpansion = true;
+ bool OldInExpansion = getInExpansion();
+ setInExpansion(true);
// We parse the macro call into a new line.
auto Args = parseMacroCall(SavedPPState);
- InExpansion = OldInExpansion;
+ setInExpansion(OldInExpansion);
assert(Line->Tokens.front().Tok == ID);
// And remember the unexpanded macro call tokens.
auto UnexpandedLine = std::move(Line);
@@ -5319,12 +5321,12 @@ UnwrappedLineParser::parseMacroCall(const PPState &SavedPPState) {
void UnwrappedLineParser::pushToken(FormatToken *Tok) {
Line->Tokens.push_back(UnwrappedLineNode(Tok));
- if (PP.AtEndOfPPLine) {
+ if (PP.getAtEndOfPPLine()) {
auto &Tok = *Line->Tokens.back().Tok;
Tok.MustBreakBefore = true;
Tok.MustBreakBeforeFinalized = true;
Tok.FirstAfterPPLine = true;
- PP.AtEndOfPPLine = false;
+ PP.setAtEndOfPPLine(false);
}
}
diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h
index 2e1755ad3b2c6..0073bfc69b26a 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -17,6 +17,7 @@
#include "Macros.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <stack>
namespace clang {
@@ -299,7 +300,8 @@ class UnwrappedLineParser {
// For recursive macro expansions, trigger reconstruction only on the
// outermost expansion.
- bool InExpansion = false;
+ bool getInExpansion() const { return NestedLambdas.getFlag(0); }
+ void setInExpansion(bool Value) { NestedLambdas.setFlag(0, Value); }
// Set while we reconstruct a macro call.
// For reconstruction, we feed the expanded lines into the reconstructor
@@ -333,7 +335,8 @@ class UnwrappedLineParser {
llvm::BitVector DeclarationScopeStack;
const FormatStyle &Style;
- bool IsCpp;
+ bool getIsCpp() const { return NestedLambdas.getFlag(1); }
+ void setIsCpp(bool Value) { NestedLambdas.setFlag(1, Value); }
LangOptions LangOpts;
const AdditionalKeywords &Keywords;
@@ -350,11 +353,14 @@ class UnwrappedLineParser {
// Keeps a stack of the states of nested lambdas (true if the return type of
// the lambda is `decltype(auto)`).
- SmallVector<bool, 4> NestedLambdas;
+ llvm::SmallVectorWithFlags<bool, 4, 3> NestedLambdas;
// Whether the parser is parsing the body of a function whose return type is
// `decltype(auto)`.
- bool IsDecltypeAutoFunction = false;
+ bool getIsDecltypeAutoFunction() const { return NestedLambdas.getFlag(2); }
+ void setIsDecltypeAutoFunction(bool Value) {
+ NestedLambdas.setFlag(2, Value);
+ }
// Represents preprocessor branch type, so we can find matching
// #if/#else/#endif directives.
@@ -409,7 +415,7 @@ class UnwrappedLineParser {
SmallVector<int, 8> LevelBranchIndex;
// Contains the maximum number of branches at each nesting level.
- SmallVector<int, 8> LevelBranchCount;
+ llvm::SmallVectorWithFlags<int, 8> LevelBranchCount;
// Contains the number of branches per nesting level we are currently
// in while parsing a preprocessor branch sequence.
@@ -425,7 +431,11 @@ class UnwrappedLineParser {
FormatToken *IncludeGuardToken = nullptr;
// Has just finished parsing a preprocessor line.
- bool AtEndOfPPLine = false;
+ bool getAtEndOfPPLine() const { return LevelBranchCount.getFlag(0); }
+ bool setAtEndOfPPLine(bool Value) {
+ LevelBranchCount.setFlag(0, Value);
+ return Value;
+ }
} PP;
// The hash tokens of the parsed preprocessor directives. The lines of a
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index cd2feb3a5964b..bf976d72d7f48 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -346,7 +346,7 @@ static void
AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
unsigned Column, bool RightJustify,
ArrayRef<unsigned> Matches,
- SmallVector<WhitespaceManager::Change, 16> &Changes) {
+ MutableArrayRef<WhitespaceManager::Change> Changes) {
unsigned OriginalMatchColumn = 0;
int Shift = 0;
@@ -504,7 +504,7 @@ enum class AlignStrategy { Normal, Macro, CaseBody, CaseColon };
// lookahead.
template <typename F, AlignStrategy Strategy = AlignStrategy::Normal>
static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
- SmallVector<WhitespaceManager::Change, 16> &Changes,
+ MutableArrayRef<WhitespaceManager::Change> Changes,
unsigned StartAt,
const FormatStyle::AlignConsecutiveStyle &ACS = {},
bool RightJustify = false) {
@@ -1670,7 +1670,7 @@ void WhitespaceManager::appendNewlineText(std::string &Text, const Change &C) {
if (C.NewlinesBefore <= 0)
return;
- StringRef Newline = UseCRLF ? "\r\n" : "\n";
+ StringRef Newline = getUseCRLF() ? "\r\n" : "\n";
Text.append(Newline);
if (C.Tok->HasFormFeedBefore)
@@ -1688,7 +1688,7 @@ void WhitespaceManager::appendEscapedNewlineText(
std::max<int>(1, EscapedNewlineColumn - PreviousEndOfTokenColumn - 1);
for (unsigned i = 0; i < Newlines; ++i) {
Text.append(Spaces, ' ');
- Text.append(UseCRLF ? "\\\r\n" : "\\\n");
+ Text.append(getUseCRLF() ? "\\\r\n" : "\\\n");
Spaces = std::max<int>(0, EscapedNewlineColumn - 1);
}
}
diff --git a/clang/lib/Format/WhitespaceManager.h b/clang/lib/Format/WhitespaceManager.h
index 66a064ae81dbf..eb837a6875a5d 100644
--- a/clang/lib/Format/WhitespaceManager.h
+++ b/clang/lib/Format/WhitespaceManager.h
@@ -17,6 +17,7 @@
#include "TokenAnnotator.h"
#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
namespace format {
@@ -36,9 +37,10 @@ class WhitespaceManager {
public:
WhitespaceManager(const SourceManager &SourceMgr, const FormatStyle &Style,
bool UseCRLF)
- : SourceMgr(SourceMgr), Style(Style), UseCRLF(UseCRLF) {}
+ : Changes(decltype(this->Changes)::withFlags(unsigned(UseCRLF))),
+ SourceMgr(SourceMgr), Style(Style) {}
- bool useCRLF() const { return UseCRLF; }
+ bool useCRLF() const { return getUseCRLF(); }
/// Infers whether the input is using CRLF.
static bool inputUsesCRLF(StringRef Text, bool DefaultToCRLF);
@@ -375,11 +377,12 @@ class WhitespaceManager {
unsigned appendTabIndent(std::string &Text, unsigned Spaces,
unsigned Indentation);
- SmallVector<Change, 16> Changes;
+ llvm::SmallVectorWithFlags<Change, 16> Changes;
const SourceManager &SourceMgr;
tooling::Replacements Replaces;
const FormatStyle &Style;
- bool UseCRLF;
+ bool getUseCRLF() const { return Changes.getFlag(0); }
+ void setUseCRLF(bool Value) { Changes.setFlag(0, Value); }
};
} // namespace format
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 738fe99cef46b..f4bc2323d4d17 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -221,7 +221,9 @@ static std::atomic<unsigned> ActiveASTUnitObjects;
ASTUnit::ASTUnit(bool _MainFileIsAST)
: CodeGenOpts(std::make_unique<CodeGenOptions>()),
- MainFileIsAST(_MainFileIsAST), WantTiming(getenv("LIBCLANG_TIMING")),
+ WantTiming(getenv("LIBCLANG_TIMING")),
+ PreambleDiagnostics(decltype(this->PreambleDiagnostics)::withFlags(
+ (unsigned(_MainFileIsAST) << 3))),
ShouldCacheCodeCompletionResults(false),
IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
UnsafeToFree(false) {
@@ -231,7 +233,7 @@ ASTUnit::ASTUnit(bool _MainFileIsAST)
ASTUnit::~ASTUnit() {
// If we loaded from an AST file, balance out the BeginSourceFile call.
- if (MainFileIsAST && getDiagnostics().getClient()) {
+ if (getMainFileIsAST() && getDiagnostics().getClient()) {
getDiagnostics().getClient()->EndSourceFile();
}
@@ -711,7 +713,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
}();
AST->LangOpts = std::make_unique<LangOptions>(LangOpts);
- AST->OnlyLocalDecls = OnlyLocalDecls;
+ AST->setOnlyLocalDeclsFlag(OnlyLocalDecls);
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->DiagOpts = DiagOpts;
AST->Diagnostics = Diags;
@@ -1349,7 +1351,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build(
PreambleInvocationIn, MainFileBuffer.get(), Bounds, Diagnostics, VFS,
- PCHContainerOps, StorePreamblesInMemory, PreambleStoragePath,
+ PCHContainerOps, getStorePreamblesInMemory(), PreambleStoragePath,
Callbacks);
PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies =
@@ -1386,7 +1388,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
checkAndRemoveNonDriverDiags(NewPreambleDiags);
StoredDiagnostics = std::move(NewPreambleDiags);
- PreambleDiagnostics = std::move(NewPreambleDiagsStandalone);
+ PreambleDiagnostics.assign(std::move(NewPreambleDiagsStandalone));
// If the hash of top-level entities differs from the hash of the top-level
// entities the last time we rebuilt the preamble, clear out the completion
@@ -1432,7 +1434,7 @@ void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
Target = CI.getTargetPtr();
Reader = CI.getASTReader();
ModCache = CI.getModuleCachePtr();
- HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
+ setHadModuleLoaderFatalFailure(CI.hadModuleLoaderFatalFailure());
if (Invocation != CI.getInvocationPtr()) {
// This happens when Parse creates a copy of \c Invocation to modify.
ModifiedInvocation = CI.getInvocationPtr();
@@ -1516,7 +1518,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = std::string(ResourceFilesPath);
}
- AST->OnlyLocalDecls = OnlyLocalDecls;
+ AST->setOnlyLocalDeclsFlag(OnlyLocalDecls);
AST->CaptureDiagnostics = CaptureDiagnostics;
if (PrecompilePreambleAfterNParses > 0)
AST->PreambleRebuildCountdown = PrecompilePreambleAfterNParses;
@@ -1688,7 +1690,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
*AST->CodeGenOpts = CI->getCodeGenOpts();
AST->DiagOpts = DiagOpts;
AST->Diagnostics = Diags;
- AST->OnlyLocalDecls = OnlyLocalDecls;
+ AST->setOnlyLocalDeclsFlag(OnlyLocalDecls);
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->TUKind = TUKind;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
@@ -2190,7 +2192,7 @@ void ASTUnit::CodeComplete(
}
bool ASTUnit::Save(StringRef File) {
- if (HadModuleLoaderFatalFailure)
+ if (getHadModuleLoaderFatalFailure())
return true;
// FIXME: Can we somehow regenerate the stat cache here, or do we need to
diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp
index 7a552a572ca78..e3003aed327b7 100644
--- a/clang/lib/Frontend/ChainedIncludesSource.cpp
+++ b/clang/lib/Frontend/ChainedIncludesSource.cpp
@@ -183,7 +183,7 @@ clang::createChainedIncludesSource(CompilerInstance &CI,
ParseAST(Clang->getSema());
Clang->getDiagnosticClient().EndSourceFile();
- assert(Buffer->IsComplete && "serialization did not complete");
+ assert(Buffer->getIsComplete() && "serialization did not complete");
auto &serialAST = Buffer->Data;
SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
StringRef(serialAST.data(), serialAST.size())));
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index f122208d6b4c8..1510318a2e039 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -615,7 +615,7 @@ struct ReadModuleNames : ASTReaderListener {
for (const std::string &LoadedModule : LoadedModules) {
if (Module *M = PP.getHeaderSearchInfo().getModuleMap().findOrLoadModule(
LoadedModule)) {
- M->HasIncompatibleModuleFile = true;
+ M->setHasIncompatibleModuleFile(true);
// Mark module as available if the only reason it was unavailable
// was missing headers.
@@ -623,8 +623,9 @@ struct ReadModuleNames : ASTReaderListener {
Stack.push_back(M);
while (!Stack.empty()) {
Module *Current = Stack.pop_back_val();
- if (Current->IsUnimportable) continue;
- Current->IsAvailable = true;
+ if (Current->getIsUnimportable())
+ continue;
+ Current->setIsAvailable(true);
auto SubmodulesRange = Current->submodules();
llvm::append_range(Stack, SubmodulesRange);
}
@@ -1477,7 +1478,7 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompile(
auto Instance = cloneForModuleCompileImpl(
ImportLoc, ModuleName,
- FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem),
+ FrontendInputFile(FakeModuleMapFile, IK, +Module->getIsSystem()),
ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName,
Module->getDirectoryDependencies(), std::move(ThreadSafeConfig));
@@ -1960,7 +1961,7 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
return nullptr;
}
if (ModuleFilename.empty()) {
- if (M && M->HasIncompatibleModuleFile) {
+ if (M && M->getHasIncompatibleModuleFile()) {
// We tried and failed to load a module file for this module. Fall
// back to textual inclusion for its headers.
return ModuleLoadResult::ConfigMismatch;
@@ -2155,7 +2156,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
while (!Worklist.empty()) {
clang::Module *M = Worklist.back();
Worklist.pop_back();
- M->IsFromModuleFile = true;
+ M->setIsFromModuleFile(true);
for (clang::Module *SubM : M->submodules())
Worklist.push_back(SubM);
}
@@ -2272,7 +2273,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
// Make the named module visible, if it's not already part of the module
// we are parsing.
if (ModuleName != getLangOpts().CurrentModule) {
- if (!Module->IsFromModuleFile && !MapPrivateSubModToTopLevel) {
+ if (!Module->getIsFromModuleFile() && !MapPrivateSubModToTopLevel) {
// We have an umbrella header or directory that doesn't actually include
// all of the headers within the directory it covers. Complain about
// this missing submodule and recover by forgetting that we ever saw
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 001ad1fd1e654..883d43e3d781f 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -630,7 +630,7 @@ static std::error_code collectModuleHeaderIncludes(
// the module map file) so this will find the same file that we found
// while parsing the module map.
addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
- Module->IsExternC);
+ Module->getIsExternC());
}
}
// Note that Module->PrivateHeaders will not be a TopHeader.
@@ -641,7 +641,7 @@ static std::error_code collectModuleHeaderIncludes(
if (Module->Parent)
// Include the umbrella header for submodules.
addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
- Includes, LangOpts, Module->IsExternC);
+ Includes, LangOpts, Module->getIsExternC());
} else if (std::optional<Module::DirectoryName> UmbrellaDir =
Module->getUmbrellaDirAsWritten()) {
// Add all of the headers we find in this subdirectory.
@@ -697,7 +697,7 @@ static std::error_code collectModuleHeaderIncludes(
// Include this header as part of the umbrella directory.
Module->addTopHeader(*Header);
- addHeaderInclude(RelPath, Includes, LangOpts, Module->IsExternC);
+ addHeaderInclude(RelPath, Includes, LangOpts, Module->getIsExternC());
}
}
@@ -802,8 +802,8 @@ static Module *prepareToBuildModule(CompilerInstance &CI,
}
if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
CI.getSourceManager().getMainFileID())) {
- auto FileCharacter =
- M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
+ auto FileCharacter = M->getIsSystem() ? SrcMgr::C_System_ModuleMap
+ : SrcMgr::C_User_ModuleMap;
FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(
*OriginalModuleMap, FileCharacter);
CI.getPreprocessor()
@@ -839,7 +839,7 @@ getInputBufferForModule(CompilerInstance &CI, Module *M) {
if (std::optional<Module::Header> UmbrellaHeader =
M->getUmbrellaHeaderAsWritten())
addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
- HeaderContents, CI.getLangOpts(), M->IsExternC);
+ HeaderContents, CI.getLangOpts(), M->getIsExternC());
Err = collectModuleHeaderIncludes(
CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), M,
@@ -1204,7 +1204,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
return false;
// Reinitialize the main file entry to refer to the new input.
- auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
+ auto Kind =
+ CurrentModule->getIsSystem() ? SrcMgr::C_System : SrcMgr::C_User;
auto &SourceMgr = CI.getSourceManager();
auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
assert(BufferID.isValid() && "couldn't create module buffer ID");
@@ -1331,7 +1332,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (!CI.loadModuleFile(ModuleFileName::makeExplicit(ModuleFile), Loaded))
return false;
- if (Loaded && Loaded->StandardCXXModule)
+ if (Loaded && Loaded->getStandardCXXModule())
CI.getDiagnostics().Report(
diag::warn_eagerly_load_for_standard_cplusplus_modules);
}
@@ -1342,7 +1343,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (!CI.loadModuleFile(ModuleFile, Loaded))
return false;
- if (Loaded && Loaded->StandardCXXModule)
+ if (Loaded && Loaded->getStandardCXXModule())
CI.getDiagnostics().Report(
diag::warn_eagerly_load_for_standard_cplusplus_modules);
}
diff --git a/clang/lib/Frontend/HeaderIncludeGen.cpp b/clang/lib/Frontend/HeaderIncludeGen.cpp
index fc45b295d4e14..9b27e9916d792 100644
--- a/clang/lib/Frontend/HeaderIncludeGen.cpp
+++ b/clang/lib/Frontend/HeaderIncludeGen.cpp
@@ -12,6 +12,7 @@
#include "clang/Frontend/Utils.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -79,17 +80,19 @@ class HeaderIncludesCallback : public PPCallbacks {
class HeaderIncludesJSONCallback : public PPCallbacks {
SourceManager &SM;
raw_ostream *OutputFile;
- bool OwnsOutputFile;
- SmallVector<std::string, 16> IncludedHeaders;
+ bool getOwnsOutputFile() const { return IncludedHeaders.getFlag(0); }
+ void setOwnsOutputFile(bool Value) { IncludedHeaders.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<std::string, 16> IncludedHeaders;
public:
HeaderIncludesJSONCallback(const Preprocessor *PP, raw_ostream *OutputFile_,
bool OwnsOutputFile_)
: SM(PP->getSourceManager()), OutputFile(OutputFile_),
- OwnsOutputFile(OwnsOutputFile_) {}
+ IncludedHeaders(
+ decltype(IncludedHeaders)::withFlags(unsigned(OwnsOutputFile_))) {}
~HeaderIncludesJSONCallback() override {
- if (OwnsOutputFile)
+ if (getOwnsOutputFile())
delete OutputFile;
}
diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp
index 9bf18b4d897ce..fceca3f9af86f 100644
--- a/clang/lib/Frontend/PrecompiledPreamble.cpp
+++ b/clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -258,7 +258,7 @@ class PrecompilePreambleAction : public ASTFrontendAction {
void setEmittedPreamblePCH(ASTWriter &Writer) {
if (FileOS) {
- *FileOS << Buffer->Data;
+ *FileOS << StringRef(Buffer->Data.data(), Buffer->Data.size());
// Make sure it hits disk now.
FileOS.reset();
}
diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
index 20bfd35e2a7d3..6a766468acc8e 100644
--- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -17,6 +17,7 @@
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitstream/BitCodes.h"
#include "llvm/Support/FileSystem.h"
@@ -44,8 +45,8 @@ class AbbreviationMap {
}
};
-typedef SmallVector<uint64_t, 64> RecordData;
-typedef SmallVectorImpl<uint64_t> RecordDataImpl;
+typedef llvm::SmallVectorWithFlags<uint64_t, 64> RecordData;
+typedef llvm::SmallVectorWithFlagsImpl<uint64_t> RecordDataImpl;
typedef ArrayRef<uint64_t> RecordDataRef;
class SDiagsWriter;
@@ -238,8 +239,7 @@ class SDiagsWriter : public DiagnosticConsumer {
/// consumer.
struct SharedState {
SharedState(StringRef File, DiagnosticOptions &DiagOpts)
- : DiagOpts(DiagOpts), Stream(Buffer), OutputFile(File.str()),
- EmittedAnyDiagBlocks(false) {}
+ : DiagOpts(DiagOpts), Stream(Buffer), OutputFile(File.str()) {}
/// Diagnostic options.
DiagnosticOptions DiagOpts;
@@ -277,7 +277,8 @@ class SDiagsWriter : public DiagnosticConsumer {
/// Whether we have already started emission of any DIAG blocks. Once
/// this becomes \c true, we never close a DIAG block until we know that we're
/// starting another one or we're done.
- bool EmittedAnyDiagBlocks;
+ bool getEmittedAnyDiagBlocks() const { return Record.getFlag(0); }
+ void setEmittedAnyDiagBlocks(bool Value) { Record.setFlag(0, Value); }
/// Engine for emitting diagnostics about the diagnostics.
std::unique_ptr<DiagnosticsEngine> MetaDiagnostics;
@@ -582,11 +583,11 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
// for beginDiagnostic, in case associated notes are emitted before we get
// there.
if (DiagLevel != DiagnosticsEngine::Note) {
- if (State->EmittedAnyDiagBlocks)
+ if (State->getEmittedAnyDiagBlocks())
ExitDiagBlock();
EnterDiagBlock();
- State->EmittedAnyDiagBlocks = true;
+ State->setEmittedAnyDiagBlocks(true);
}
// Compute the diagnostic text.
@@ -777,11 +778,11 @@ SDiagsWriter::~SDiagsWriter() {
return;
// Finish off any diagnostic we were in the process of emitting.
- if (State->EmittedAnyDiagBlocks)
+ if (State->getEmittedAnyDiagBlocks())
ExitDiagBlock();
if (MergeChildRecords) {
- if (!State->EmittedAnyDiagBlocks)
+ if (!State->getEmittedAnyDiagBlocks())
// We have no diagnostics of our own, so we can just leave the child
// process' output alone
return;
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index 6f599ababcaf5..7b4d3f98e1dea 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/TypeLoc.h"
#include "clang/Sema/HeuristicResolver.h"
#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
using namespace clang;
using namespace index;
@@ -23,16 +24,18 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
IndexingContext &IndexCtx;
const NamedDecl *Parent;
const DeclContext *ParentDC;
- bool IsBase;
- SmallVector<SymbolRelation, 3> Relations;
+ bool getIsBase() const { return Relations.getFlag(0); }
+ void setIsBase(bool Value) { Relations.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<SymbolRelation, 3> Relations;
typedef RecursiveASTVisitor<TypeIndexer> base;
public:
TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
const DeclContext *DC, bool isBase, bool isIBType)
- : IndexCtx(indexCtx), Parent(parent), ParentDC(DC), IsBase(isBase) {
- if (IsBase) {
+ : IndexCtx(indexCtx), Parent(parent), ParentDC(DC),
+ Relations(decltype(this->Relations)::withFlags(unsigned(isBase))) {
+ if (getIsBase()) {
assert(Parent);
Relations.emplace_back((unsigned)SymbolRole::RelationBaseOf, Parent);
}
@@ -65,7 +68,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
return IndexCtx.handleReference(Underlying, Loc, Parent,
ParentDC, SymbolRoleSet(), Relations);
}
- if (IsBase) {
+ if (getIsBase()) {
TRY_TO(IndexCtx.handleReference(ND, Loc,
Parent, ParentDC, SymbolRoleSet()));
if (auto *CD = TL.getType()->getAsCXXRecordDecl()) {
@@ -181,10 +184,12 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
// The relations we have to `Parent` do not apply to our template arguments,
// so clear them while visiting the args.
- SmallVector<SymbolRelation, 3> SavedRelations = Relations;
+ SmallVector<SymbolRelation, 3> SavedRelations(Relations.begin(),
+ Relations.end());
Relations.clear();
- llvm::scope_exit ResetSavedRelations(
- [&] { this->Relations = SavedRelations; });
+ llvm::scope_exit ResetSavedRelations([&] {
+ this->Relations.assign(SavedRelations.begin(), SavedRelations.end());
+ });
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
if (!TraverseTemplateArgumentLoc(TL.getArgLoc(I)))
return false;
diff --git a/clang/lib/Lex/DependencyDirectivesScanner.cpp b/clang/lib/Lex/DependencyDirectivesScanner.cpp
index 76a2a0e698a8a..c74404641fdaa 100644
--- a/clang/lib/Lex/DependencyDirectivesScanner.cpp
+++ b/clang/lib/Lex/DependencyDirectivesScanner.cpp
@@ -22,6 +22,7 @@
#include "clang/Lex/Pragma.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
#include <optional>
@@ -186,7 +187,12 @@ struct Scanner {
/// true at the end.
bool reportError(const char *CurPtr, unsigned Err);
- bool ScanningPreprocessedModuleFile = false;
+ bool getScanningPreprocessedModuleFile() const {
+ return DirsWithToks.getFlag(0);
+ }
+ void setScanningPreprocessedModuleFile(bool Value) {
+ DirsWithToks.setFlag(0, Value);
+ }
StringMap<char> SplitIds;
StringRef Input;
SmallVectorImpl<dependency_directives_scan::Token> &Tokens;
@@ -201,7 +207,7 @@ struct Scanner {
/// The directives that were lexed along with the number of tokens that each
/// directive contains. The tokens of all the directives are kept in \p Tokens
/// vector, in the same order as the directives order in \p DirsWithToks.
- SmallVector<DirectiveWithTokens, 64> DirsWithToks;
+ llvm::SmallVectorWithFlags<DirectiveWithTokens, 64> DirsWithToks;
LangOptions LangOpts;
Lexer TheLexer;
};
@@ -735,9 +741,9 @@ bool Scanner::lexModule(const char *&First, const char *const End) {
}
StringRef Module =
- ScanningPreprocessedModuleFile ? "__preprocessed_module" : "module";
+ getScanningPreprocessedModuleFile() ? "__preprocessed_module" : "module";
StringRef Import =
- ScanningPreprocessedModuleFile ? "__preprocessed_import" : "import";
+ getScanningPreprocessedModuleFile() ? "__preprocessed_import" : "import";
if (Id != Module && Id != Import) {
skipLine(First, End);
@@ -1059,7 +1065,7 @@ bool Scanner::scanImpl(const char *First, const char *const End) {
}
bool Scanner::scan(SmallVectorImpl<Directive> &Directives) {
- ScanningPreprocessedModuleFile = clang::isPreprocessedModuleFile(Input);
+ setScanningPreprocessedModuleFile(clang::isPreprocessedModuleFile(Input));
bool Error = scanImpl(Input.begin(), Input.end());
if (!Error) {
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 906ce07b96a79..a752d266f30ac 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -617,7 +617,7 @@ getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
static bool needModuleLookup(Module *RequestingModule,
bool HasSuggestedModule) {
return HasSuggestedModule ||
- (RequestingModule && RequestingModule->NoUndeclaredIncludes);
+ (RequestingModule && RequestingModule->getNoUndeclaredIncludes());
}
/// DoFrameworkLookup - Do a lookup of the specified file in the current
@@ -1880,7 +1880,8 @@ static bool suggestModule(HeaderSearch &HS, ModuleMap::KnownHeader Module,
ModuleMap::KnownHeader *SuggestedModule) {
// If this module specifies [no_undeclared_includes], we cannot find any
// file that's in a non-dependency module.
- if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
+ if (RequestingModule && Module &&
+ RequestingModule->getNoUndeclaredIncludes()) {
HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/ false);
if (!RequestingModule->directlyUses(Module.getModule())) {
// Builtin headers are a special case. Multiple modules can use the same
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index b659780bac593..33f39eebd6e7c 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -27,6 +27,7 @@
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
@@ -37,6 +38,7 @@
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/Unicode.h"
#include "llvm/Support/UnicodeCharRanges.h"
+#include <memory>
#include <algorithm>
#include <cassert>
@@ -171,16 +173,16 @@ void Lexer::InitLexer(const char *BufStart, const char *BufPtr,
HasLeadingEmptyMacro = false;
// We are not after parsing a #.
- ParsingPreprocessorDirective = false;
+ setParsingPreprocessorDirectiveFlag(false);
// We are not after parsing #include.
- ParsingFilename = false;
+ setParsingFilename(false);
// We are not in raw mode. Raw mode disables diagnostics and interpretation
// of tokens (e.g. identifiers, thus disabling macro expansion). It is used
// to quickly lex the tokens of the buffer, e.g. when handling a "#if 0" block
// or otherwise skipping over tokens.
- LexingRawMode = false;
+ setLexingRawMode(false);
// Default to not keeping comments.
ExtendedTokenMode = 0;
@@ -215,7 +217,7 @@ Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts,
InitLexer(BufStart, BufPtr, BufEnd);
// We *are* in raw mode.
- LexingRawMode = true;
+ setLexingRawMode(true);
}
/// Lexer constructor - Create a new raw lexer object. This object is only
@@ -278,7 +280,7 @@ std::unique_ptr<Lexer> Lexer::Create_PragmaLexer(
// Ensure that the lexer thinks it is inside a directive, so that end \n will
// return an EOD token.
- L->ParsingPreprocessorDirective = true;
+ L->setParsingPreprocessorDirectiveFlag(true);
// This lexer really is for _Pragma.
L->Is_PragmaLexer = true;
@@ -1860,7 +1862,7 @@ bool Lexer::tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size,
return false;
bool DiagnoseAndContinue = !isLexingRawMode() &&
- !ParsingPreprocessorDirective &&
+ !getParsingPreprocessorDirectiveFlag() &&
!PP->isPreprocessedOutput();
if (!CheckCodepointValidInIdentifier(
PP, LangOpts, CodePoint, makeCharRange(*this, CurPtr, UCNPtr),
@@ -1915,7 +1917,7 @@ bool Lexer::tryConsumeIdentifierUTF8Char(const char *&CurPtr, Token &Result) {
return false;
bool DiagnoseAndContinue = !isLexingRawMode() &&
- !ParsingPreprocessorDirective &&
+ !getParsingPreprocessorDirectiveFlag() &&
!PP->isPreprocessedOutput();
if (!CheckCodepointValidInIdentifier(
@@ -1951,7 +1953,7 @@ bool Lexer::LexUnicodeIdentifierStart(Token &Result, uint32_t C,
const char *CurPtr) {
bool IsExtension = false;
if (isAllowedInitiallyIDChar(C, LangOpts, IsExtension)) {
- if (!isLexingRawMode() && !ParsingPreprocessorDirective &&
+ if (!isLexingRawMode() && !getParsingPreprocessorDirectiveFlag() &&
!PP->isPreprocessedOutput()) {
if (IsExtension)
diagnoseMathematicalNotationInIdentifier(
@@ -1968,7 +1970,7 @@ bool Lexer::LexUnicodeIdentifierStart(Token &Result, uint32_t C,
return LexIdentifierContinue(Result, CurPtr);
}
- if (!isLexingRawMode() && !ParsingPreprocessorDirective &&
+ if (!isLexingRawMode() && !getParsingPreprocessorDirectiveFlag() &&
!PP->isPreprocessedOutput() && !isASCII(*BufferPtr) &&
!isUnicodeWhitespace(C)) {
// Non-ASCII characters tend to creep into source code unintentionally.
@@ -2077,7 +2079,7 @@ bool Lexer::LexIdentifierContinue(Token &Result, const char *CurPtr) {
// If we are in raw mode, return this identifier raw. There is no need to
// look up identifier information or attempt to macro expand it.
- if (LexingRawMode)
+ if (getLexingRawMode())
return true;
// Fill in Result.IdentifierInfo and update the token kind,
@@ -2338,7 +2340,7 @@ bool Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
// The implementation-defined semantics cannot be taken as causing '\' to
// "escape" the following " because there is no provision for " in a
// q-char-sequence.
- if (ParsingFilename && C == '"')
+ if (getParsingFilename() && C == '"')
CurPtr = SavedCurPtr;
}
@@ -2352,7 +2354,7 @@ bool Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
if (C == 0) {
if (isCodeCompletionPoint(CurPtr-1)) {
- if (ParsingFilename)
+ if (getParsingFilename())
codeCompleteIncludedFile(AfterQuote, CurPtr - 1, /*IsAngled=*/false);
else
PP->CodeCompleteNaturalLanguage();
@@ -2643,7 +2645,7 @@ bool Lexer::SkipWhitespace(Token &Result, const char *CurPtr) {
if (!isVerticalWhitespace(Char))
break;
- if (ParsingPreprocessorDirective) {
+ if (getParsingPreprocessorDirectiveFlag()) {
// End of preprocessor directive line, let LexTokenInternal handle this.
BufferPtr = CurPtr;
return false;
@@ -2774,9 +2776,9 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr) {
// we'll handle it below.
const char *OldPtr = CurPtr;
bool OldRawMode = isLexingRawMode();
- LexingRawMode = true;
+ setLexingRawMode(true);
C = getAndAdvanceChar(CurPtr, Result);
- LexingRawMode = OldRawMode;
+ setLexingRawMode(OldRawMode);
// If we only read only one character, then no special handling is needed.
// We're done and can skip forward to the newline.
@@ -2835,7 +2837,7 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr) {
// If we are inside a preprocessor directive and we see the end of line,
// return immediately, so that the lexer can return this as an EOD token.
- if (ParsingPreprocessorDirective || CurPtr == BufferEnd) {
+ if (getParsingPreprocessorDirectiveFlag() || CurPtr == BufferEnd) {
BufferPtr = CurPtr;
return false;
}
@@ -2863,7 +2865,7 @@ bool Lexer::SaveLineComment(Token &Result, const char *CurPtr) {
// directly.
FormTokenWithChars(Result, CurPtr, tok::comment);
- if (!ParsingPreprocessorDirective || LexingRawMode)
+ if (!getParsingPreprocessorDirectiveFlag() || getLexingRawMode())
return true;
// If this Line-style comment is in a macro definition, transmogrify it into
@@ -3195,7 +3197,8 @@ bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) {
/// ReadToEndOfLine - Read the rest of the current preprocessor line as an
/// uninterpreted string. This switches the lexer out of directive mode.
void Lexer::ReadToEndOfLine(SmallVectorImpl<char> *Result) {
- assert(ParsingPreprocessorDirective && ParsingFilename == false &&
+ assert(getParsingPreprocessorDirectiveFlag() &&
+ getParsingFilename() == false &&
"Must be in a preprocessing directive!");
Token Tmp;
Tmp.startToken();
@@ -3254,9 +3257,9 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
// If we hit the end of the file while parsing a preprocessor directive,
// end the preprocessor directive first. The next token returned will
// then be the end of file.
- if (ParsingPreprocessorDirective) {
+ if (getParsingPreprocessorDirectiveFlag()) {
// Done parsing the "line".
- ParsingPreprocessorDirective = false;
+ setParsingPreprocessorDirectiveFlag(false);
// Update the location of token as well as BufferPtr.
FormTokenWithChars(Result, CurPtr, tok::eod);
@@ -3312,7 +3315,8 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
/// buffer controlled by this lexer, otherwise return the next unexpanded
/// token.
std::optional<Token> Lexer::peekNextPPToken() {
- assert(!LexingRawMode && "How can we expand a macro from a skipping buffer?");
+ assert(!getLexingRawMode() &&
+ "How can we expand a macro from a skipping buffer?");
if (isDependencyDirectivesLexer()) {
if (NextDepDirectiveTokenIndex == DepDirectives.front().Tokens.size())
@@ -3326,11 +3330,11 @@ std::optional<Token> Lexer::peekNextPPToken() {
// Switch to 'skipping' mode. This will ensure that we can lex a token
// without emitting diagnostics, disables macro expansion, and will cause EOF
// to return an EOF token instead of popping the include stack.
- LexingRawMode = true;
+ setLexingRawMode(true);
// Save state that can be changed while lexing so that we can restore it.
const char *TmpBufferPtr = BufferPtr;
- bool inPPDirectiveMode = ParsingPreprocessorDirective;
+ bool inPPDirectiveMode = getParsingPreprocessorDirectiveFlag();
bool atStartOfLine = IsAtStartOfLine;
bool atPhysicalStartOfLine = IsAtPhysicalStartOfLine;
bool leadingSpace = HasLeadingSpace;
@@ -3341,13 +3345,13 @@ std::optional<Token> Lexer::peekNextPPToken() {
// Restore state that may have changed.
BufferPtr = TmpBufferPtr;
- ParsingPreprocessorDirective = inPPDirectiveMode;
+ setParsingPreprocessorDirectiveFlag(inPPDirectiveMode);
HasLeadingSpace = leadingSpace;
IsAtStartOfLine = atStartOfLine;
IsAtPhysicalStartOfLine = atPhysicalStartOfLine;
MIOpt = MIOptState;
// Restore the lexer back to non-skipping mode.
- LexingRawMode = false;
+ setLexingRawMode(false);
if (Tok.is(tok::eof))
return std::nullopt;
@@ -3473,7 +3477,8 @@ static const char *findPlaceholderEnd(const char *CurPtr,
bool Lexer::lexEditorPlaceholder(Token &Result, const char *CurPtr) {
assert(CurPtr[-1] == '<' && CurPtr[0] == '#' && "Not a placeholder!");
- if (!PP || !PP->getPreprocessorOpts().LexEditorPlaceholders || LexingRawMode)
+ if (!PP || !PP->getPreprocessorOpts().LexEditorPlaceholders ||
+ getLexingRawMode())
return false;
const char *End = findPlaceholderEnd(CurPtr + 1, BufferEnd);
if (!End)
@@ -3935,9 +3940,9 @@ bool Lexer::LexTokenInternal(Token &Result) {
case '\n':
// If we are inside a preprocessor directive and we see the end of line,
// we know we are done with the directive, so return an EOD token.
- if (ParsingPreprocessorDirective) {
+ if (getParsingPreprocessorDirectiveFlag()) {
// Done parsing the "line".
- ParsingPreprocessorDirective = false;
+ setParsingPreprocessorDirectiveFlag(false);
// Restore comment saving mode, in case it was disabled for directive.
if (PP)
@@ -4166,8 +4171,8 @@ bool Lexer::LexTokenInternal(Token &Result) {
// Notify MIOpt that we read a non-whitespace/non-comment token.
MIOpt.ReadToken();
return LexStringLiteral(Result, CurPtr,
- ParsingFilename ? tok::header_name
- : tok::string_literal);
+ getParsingFilename() ? tok::header_name
+ : tok::string_literal);
// C99 6.4.6: Punctuators.
case '?':
@@ -4343,7 +4348,7 @@ bool Lexer::LexTokenInternal(Token &Result) {
// it's actually the start of a preprocessing directive. Callback to
// the preprocessor to handle it.
// TODO: -fpreprocessed mode??
- if (Result.isAtPhysicalStartOfLine() && !LexingRawMode &&
+ if (Result.isAtPhysicalStartOfLine() && !getLexingRawMode() &&
!Is_PragmaLexer)
goto HandleDirective;
@@ -4355,7 +4360,7 @@ bool Lexer::LexTokenInternal(Token &Result) {
break;
case '<':
Char = getCharAndSize(CurPtr, SizeTmp);
- if (ParsingFilename && LexAngledStringLiteral(Result, CurPtr))
+ if (getParsingFilename() && LexAngledStringLiteral(Result, CurPtr))
return true;
if (Char == '<') {
@@ -4536,7 +4541,8 @@ bool Lexer::LexTokenInternal(Token &Result) {
// it's actually the start of a preprocessing directive. Callback to
// the preprocessor to handle it.
// TODO: -fpreprocessed mode??
- if (Result.isAtPhysicalStartOfLine() && !LexingRawMode && !Is_PragmaLexer)
+ if (Result.isAtPhysicalStartOfLine() && !getLexingRawMode() &&
+ !Is_PragmaLexer)
goto HandleDirective;
Kind = tok::hash;
@@ -4547,13 +4553,20 @@ bool Lexer::LexTokenInternal(Token &Result) {
// Objective C support.
if (CurPtr[-1] == '@' && LangOpts.ObjC) {
FormTokenWithChars(Result, CurPtr, tok::at);
- if (PP && Result.isAtPhysicalStartOfLine() && !LexingRawMode &&
+ if (PP && Result.isAtPhysicalStartOfLine() && !getLexingRawMode() &&
!Is_PragmaLexer) {
Token NextPPTok;
NextPPTok.startToken();
{
- llvm::SaveAndRestore<bool> SavedParsingPreprocessorDirective(
- this->ParsingPreprocessorDirective, true);
+ auto SavedParsingPreprocessorDirective = [PackedFlagOwner_ = this] {
+ const bool PackedFlagOld_ =
+ PackedFlagOwner_->getParsingPreprocessorDirectiveFlag();
+ PackedFlagOwner_->setParsingPreprocessorDirectiveFlag(true);
+ return llvm::scope_exit([PackedFlagOwner_, PackedFlagOld_] {
+ PackedFlagOwner_->setParsingPreprocessorDirectiveFlag(
+ PackedFlagOld_);
+ });
+ }();
auto NextTokOr = peekNextPPToken();
if (NextTokOr.has_value()) {
NextPPTok = *NextTokOr;
@@ -4618,7 +4631,7 @@ bool Lexer::LexTokenInternal(Token &Result) {
return LexUnicodeIdentifierStart(Result, CodePoint, CurPtr);
}
- if (isLexingRawMode() || ParsingPreprocessorDirective ||
+ if (isLexingRawMode() || getParsingPreprocessorDirectiveFlag() ||
PP->isPreprocessedOutput()) {
++CurPtr;
Kind = tok::unknown;
@@ -4703,7 +4716,7 @@ bool Lexer::LexDependencyDirectiveToken(Token &Result) {
}
const char *DDTokPtr = BufferStart + DDTok.Offset;
- if (ParsingFilename && *DDTokPtr == '<') {
+ if (getParsingFilename() && *DDTokPtr == '<') {
Result.setFlag((clang::Token::TokenFlags)DDTok.Flags);
Result.clearFlag(clang::Token::NeedsCleaning);
BufferPtr = DDTokPtr;
@@ -4771,7 +4784,7 @@ bool Lexer::LexDependencyDirectiveToken(Token &Result) {
return true;
}
if (Result.is(tok::eod))
- ParsingPreprocessorDirective = false;
+ setParsingPreprocessorDirectiveFlag(false);
return true;
}
diff --git a/clang/lib/Lex/MacroArgs.cpp b/clang/lib/Lex/MacroArgs.cpp
index 548df16c59f6b..641ab93d73fe2 100644
--- a/clang/lib/Lex/MacroArgs.cpp
+++ b/clang/lib/Lex/MacroArgs.cpp
@@ -14,8 +14,10 @@
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/SaveAndRestore.h"
#include <algorithm>
+#include <memory>
using namespace clang;
@@ -168,7 +170,13 @@ const std::vector<Token> &MacroArgs::getPreExpArgument(unsigned Arg,
std::vector<Token> &Result = PreExpArgTokens[Arg];
if (!Result.empty()) return Result;
- SaveAndRestore PreExpandingMacroArgs(PP.InMacroArgPreExpansion, true);
+ auto PreExpandingMacroArgs = [PackedFlagOwner = std::addressof(PP)] {
+ const bool PackedFlagOld = PackedFlagOwner->getInMacroArgPreExpansion();
+ PackedFlagOwner->setInMacroArgPreExpansion(true);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setInMacroArgPreExpansion(PackedFlagOld);
+ });
+ }();
const Token *AT = getUnexpArgument(Arg);
unsigned NumToks = getArgLength(AT)+1; // Include the EOF.
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index b75f5c98ba72b..600771299536b 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -56,14 +56,14 @@ void ModuleMap::resolveLinkAsDependencies(Module *Mod) {
for (auto &Name : PendingLinkAs->second) {
auto *M = findModule(Name.getKey());
if (M)
- M->UseExportAsModuleLinkName = true;
+ M->setUseExportAsModuleLinkName(true);
}
}
}
void ModuleMap::addLinkAsDependency(Module *Mod) {
if (findModule(Mod->ExportAsModule))
- Mod->UseExportAsModuleLinkName = true;
+ Mod->setUseExportAsModuleLinkName(true);
else
PendingLinkAsModule[Mod->ExportAsModule].insert(Mod->Name);
}
@@ -111,7 +111,7 @@ ModuleMap::resolveExport(Module *Mod,
bool Complain) const {
// We may have just a wildcard.
if (Unresolved.Id.empty()) {
- assert(Unresolved.Wildcard && "Invalid unresolved export");
+ assert(Unresolved.getWildcard() && "Invalid unresolved export");
return Module::ExportDecl(nullptr, true);
}
@@ -120,11 +120,11 @@ ModuleMap::resolveExport(Module *Mod,
if (!Context)
return {};
- return Module::ExportDecl(Context, Unresolved.Wildcard);
+ return Module::ExportDecl(Context, Unresolved.getWildcard());
}
-Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
- bool Complain) const {
+Module *ModuleMap::resolveModuleId(llvm::ArrayRef<ModuleId::value_type> Id,
+ Module *Mod, bool Complain) const {
// Find the starting module.
Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
if (!Context) {
@@ -160,7 +160,7 @@ static void appendSubframeworkPaths(Module *Mod,
// Collect the framework names from the given module to the top-level module.
SmallVector<StringRef, 2> Paths;
for (; Mod; Mod = Mod->Parent) {
- if (Mod->IsFramework)
+ if (Mod->getIsFramework())
Paths.push_back(Mod->Name);
}
@@ -212,7 +212,7 @@ OptionalFileEntryRef ModuleMap::findHeader(
// 'framework module FrameworkName.Private', since a 'Private.Framework'
// does not usually exist. However, since both are currently widely used
// for private modules, make sure we find the right path in both cases.
- if (M->IsFramework && M->Name == "Private")
+ if (M->getIsFramework() && M->Name == "Private")
RelativePathName.clear();
else
RelativePathName.resize(RelativePathLength);
@@ -333,9 +333,10 @@ bool ModuleMap::resolveAsBuiltinHeader(
Module *Mod, const Module::UnresolvedHeaderDirective &Header) {
if (Header.Kind == Module::HK_Excluded ||
llvm::sys::path::is_absolute(Header.FileName) ||
- Mod->isPartOfFramework() || !Mod->IsSystem || Header.IsUmbrella ||
+ Mod->isPartOfFramework() || !Mod->getIsSystem() || Header.IsUmbrella ||
!BuiltinIncludeDir || BuiltinIncludeDir == Mod->Directory ||
- !LangOpts.BuiltinHeadersInSystemModules || !isBuiltinHeaderName(Header.FileName))
+ !LangOpts.BuiltinHeadersInSystemModules ||
+ !isBuiltinHeaderName(Header.FileName))
return false;
// This is a system module with a top-level header. This header
@@ -413,7 +414,7 @@ bool ModuleMap::isBuiltinHeader(FileEntryRef File) {
bool ModuleMap::shouldImportRelativeToBuiltinIncludeDir(StringRef FileName,
Module *Module) const {
return LangOpts.BuiltinHeadersInSystemModules && BuiltinIncludeDir &&
- Module->IsSystem && !Module->isPartOfFramework() &&
+ Module->getIsSystem() && !Module->isPartOfFramework() &&
isBuiltinHeaderName(FileName);
}
@@ -593,9 +594,9 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
} else if (RequestingModule && RequestingModuleIsModuleInterface &&
LangOpts.isCompilingModule()) {
// Do not diagnose when we are not compiling a module.
- diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
- diag::warn_non_modular_include_in_framework_module :
- diag::warn_non_modular_include_in_module;
+ diag::kind DiagID = RequestingModule->getTopLevelModule()->getIsFramework()
+ ? diag::warn_non_modular_include_in_framework_module
+ : diag::warn_non_modular_include_in_module;
Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
<< File.getName();
}
@@ -763,13 +764,13 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
while (!UmbrellaModule->getEffectiveUmbrellaDir() && UmbrellaModule->Parent)
UmbrellaModule = UmbrellaModule->Parent;
- if (UmbrellaModule->InferSubmodules) {
+ if (UmbrellaModule->getInferSubmodules()) {
FileID UmbrellaModuleMap = getModuleMapFileIDForUniquing(UmbrellaModule);
// Infer submodules for each of the directories we found between
// the directory of the umbrella header and the directory where
// the actual header is located.
- bool Explicit = UmbrellaModule->InferExplicitSubmodules;
+ bool Explicit = UmbrellaModule->getInferExplicitSubmodules();
for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
// Find or create the module that corresponds to this directory name.
@@ -785,7 +786,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
// If inferred submodules export everything they import, add a
// wildcard to the set of exports.
- if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
+ if (UmbrellaModule->getInferExportWildcard() && Result->Exports.empty())
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
}
@@ -800,7 +801,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
// If inferred submodules export everything they import, add a
// wildcard to the set of exports.
- if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
+ if (UmbrellaModule->getInferExportWildcard() && Result->Exports.empty())
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
} else {
// Record each of the directories we stepped through as being part of
@@ -897,7 +898,7 @@ bool ModuleMap::isHeaderUnavailableInModule(
UmbrellaModule->Parent)
UmbrellaModule = UmbrellaModule->Parent;
- if (UmbrellaModule->InferSubmodules) {
+ if (UmbrellaModule->getInferSubmodules()) {
for (DirectoryEntryRef SkippedDir : llvm::reverse(SkippedDirs)) {
// Find or create the module that corresponds to this directory name.
SmallString<32> NameBuf;
@@ -948,15 +949,15 @@ Module *ModuleMap::findModule(StringRef Name) const {
Module *ModuleMap::findOrInferSubmodule(Module *Parent, StringRef Name) {
if (Module *SubM = Parent->findSubmodule(Name))
return SubM;
- if (!Parent->InferSubmodules)
+ if (!Parent->getInferSubmodules())
return nullptr;
Module *Result = new (ModulesAlloc.Allocate())
Module(ModuleConstructorTag{}, Name, SourceLocation(), Parent, false,
- Parent->InferExplicitSubmodules, 0);
- Result->InferExplicitSubmodules = Parent->InferExplicitSubmodules;
- Result->InferSubmodules = Parent->InferSubmodules;
- Result->InferExportWildcard = Parent->InferExportWildcard;
- if (Result->InferExportWildcard)
+ Parent->getInferExplicitSubmodules(), 0);
+ Result->setInferExplicitSubmodules(Parent->getInferExplicitSubmodules());
+ Result->setInferSubmodules(Parent->getInferSubmodules());
+ Result->setInferExportWildcard(Parent->getInferExportWildcard());
+ if (Result->getInferExportWildcard())
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
return Result;
}
@@ -1120,7 +1121,8 @@ Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
/// For a framework module, infer the framework against which we
/// should link.
static void inferFrameworkLink(Module *Mod) {
- assert(Mod->IsFramework && "Can only infer linking for framework modules");
+ assert(Mod->getIsFramework() &&
+ "Can only infer linking for framework modules");
assert(!Mod->isSubFramework() &&
"Can only infer linking for top-level frameworks");
@@ -1192,7 +1194,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
std::make_pair(*ParentDir, InferredDirectory())).first;
}
- if (inferred->second.InferModules) {
+ if (inferred->second.getInferModules()) {
// We're allowed to infer for this directory, but make sure it's okay
// to infer this particular module.
StringRef Name = llvm::sys::path::stem(FrameworkDirName);
@@ -1238,10 +1240,12 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
ModuleScopeIDs[Result] = CurrentModuleScopeID;
}
- Result->IsSystem |= Attrs.IsSystem;
- Result->IsExternC |= Attrs.IsExternC;
- Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
- Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
+ Result->setIsSystem(int(Result->getIsSystem()) | (Attrs.IsSystem));
+ Result->setIsExternC(int(Result->getIsExternC()) | (Attrs.IsExternC));
+ Result->setConfigMacrosExhaustive(int(Result->getConfigMacrosExhaustive()) |
+ (Attrs.IsExhaustive));
+ Result->setNoUndeclaredIncludes(int(Result->getNoUndeclaredIncludes()) |
+ (Attrs.NoUndeclaredIncludes));
Result->Directory = FrameworkDir;
// Chop off the first framework bit, as that is implied.
@@ -1257,8 +1261,8 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
// module * { export * }
- Result->InferSubmodules = true;
- Result->InferExportWildcard = true;
+ Result->setInferSubmodules(true);
+ Result->setInferExportWildcard(true);
// Look for subframeworks.
std::error_code EC;
@@ -1602,7 +1606,7 @@ ModuleMap::getContainingModuleMapFile(const Module *Module) const {
}
FileID ModuleMap::getModuleMapFileIDForUniquing(const Module *M) const {
- if (M->IsInferred) {
+ if (M->getIsInferred()) {
assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
return InferredModuleAllowedBy.find(M)->second;
}
@@ -1615,7 +1619,7 @@ ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
}
void ModuleMap::setInferredModuleAllowedBy(Module *M, FileID ModMapFID) {
- M->IsInferred = true;
+ M->setIsInferred(true);
InferredModuleAllowedBy[M] = ModMapFID;
}
@@ -1694,7 +1698,8 @@ bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
auto *Top = Mod->getTopLevelModule();
- auto Unresolved = std::move(Top->UnresolvedDirectUses);
+ auto Unresolved =
+ SmallVector<ModuleId, 2>(std::move(Top->UnresolvedDirectUses));
Top->UnresolvedDirectUses.clear();
for (auto &UDU : Unresolved) {
Module *DirectUse = resolveModuleId(UDU, Top, Complain);
@@ -1836,7 +1841,7 @@ void ModuleMapLoader::diagnosePrivateModules(SourceLocation StartLoc) {
if (StartLoc.isValid())
FixItInitBegin = StartLoc;
- if (ActiveModule->Parent->IsFramework)
+ if (ActiveModule->Parent->getIsFramework())
FixedPrivModDecl.append("framework ");
FixedPrivModDecl.append("module ");
FixedPrivModDecl.append(Canonical);
@@ -1909,7 +1914,7 @@ void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
// - If the Existing module was loaded from an AST file and we've found its
// original source module map, or we cannot determine Existing's
// definition location.
- bool LoadedFromASTFile = Existing->IsFromModuleFile;
+ bool LoadedFromASTFile = Existing->getIsFromModuleFile();
if (LoadedFromASTFile) {
OptionalFileEntryRef ExistingModMapFile =
Map.getContainingModuleMapFile(Existing);
@@ -1926,7 +1931,7 @@ void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
LoadedFromASTFile = false;
}
// - If we previously inferred this module from different module map file.
- bool Inferred = Existing->IsInferred;
+ bool Inferred = Existing->getIsInferred();
// - If we're building a framework that vends a module map, we might've
// previously seen the one in intermediate products and now the system
// one.
@@ -1942,7 +1947,7 @@ void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
// that \c Existing is part of a framework iff the redefinition of FW
// we have just skipped had it too. Once we do that, stop checking
// the local framework qualifier and only rely on \c Existing.
- bool PartOfFramework = MD.Framework || Existing->isPartOfFramework();
+ bool PartOfFramework = MD.getFramework() || Existing->isPartOfFramework();
// - If we're building a (preprocessed) module and we've just loaded the
// module map file from which it was created.
bool ParsedAsMainInput =
@@ -1974,27 +1979,27 @@ void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
// Start defining this module.
if (ShadowingModule) {
- ActiveModule =
- Map.createShadowedModule(ModuleName, MD.Framework, ShadowingModule);
+ ActiveModule = Map.createShadowedModule(ModuleName, MD.getFramework(),
+ ShadowingModule);
} else {
- ActiveModule = Map.findOrCreateModuleFirst(ModuleName, ActiveModule,
- MD.Framework, MD.Explicit);
+ ActiveModule = Map.findOrCreateModuleFirst(
+ ModuleName, ActiveModule, MD.getFramework(), MD.getExplicit());
}
ActiveModule->DefinitionLoc = ModuleNameLoc;
if (MD.Attrs.IsSystem || IsSystem)
- ActiveModule->IsSystem = true;
+ ActiveModule->setIsSystem(true);
if (MD.Attrs.IsExternC)
- ActiveModule->IsExternC = true;
+ ActiveModule->setIsExternC(true);
if (MD.Attrs.NoUndeclaredIncludes)
- ActiveModule->NoUndeclaredIncludes = true;
+ ActiveModule->setNoUndeclaredIncludes(true);
ActiveModule->Directory = Directory;
StringRef MapFileName(
SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
if (MapFileName.ends_with("module.private.modulemap") ||
MapFileName.ends_with("module_private.map")) {
- ActiveModule->ModuleMapIsPrivate = true;
+ ActiveModule->setModuleMapIsPrivate(true);
}
// Private modules named as FooPrivate, Foo.Private or similar are likely a
@@ -2007,7 +2012,7 @@ void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
StartLoc) &&
!Diags.isIgnored(diag::warn_mmap_mismatched_private_module_name,
StartLoc) &&
- ActiveModule->ModuleMapIsPrivate)
+ ActiveModule->getModuleMapIsPrivate())
diagnosePrivateModules(MD.Location);
for (const modulemap::Decl &Decl : MD.Decls) {
@@ -2040,13 +2045,13 @@ void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) {
// If the active module is a top-level framework, and there are no link
// libraries, automatically link against the framework.
- if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() &&
+ if (ActiveModule->getIsFramework() && !ActiveModule->isSubFramework() &&
ActiveModule->LinkLibraries.empty())
inferFrameworkLink(ActiveModule);
// If the module meets all requirements but is still unavailable, mark the
// whole tree as unavailable to prevent it from building.
- if (!ActiveModule->IsAvailable && !ActiveModule->IsUnimportable &&
+ if (!ActiveModule->getIsAvailable() && !ActiveModule->getIsUnimportable() &&
ActiveModule->Parent) {
ActiveModule->getTopLevelModule()->markUnavailable(/*Unimportable=*/false);
ActiveModule->getTopLevelModule()->MissingHeaders.append(
@@ -2315,7 +2320,7 @@ void ModuleMapLoader::handleConfigMacros(
// TODO: Is this really the behavior we want for multiple config_macros
// declarations? If any of them are exhaustive then all of them are.
if (CMD.Exhaustive) {
- ActiveModule->ConfigMacrosExhaustive = true;
+ ActiveModule->setConfigMacrosExhaustive(true);
}
ActiveModule->ConfigMacros.insert(ActiveModule->ConfigMacros.end(),
CMD.Macros.begin(), CMD.Macros.end());
@@ -2336,20 +2341,21 @@ void ModuleMapLoader::handleInferredModuleDecl(
SourceLocation StarLoc = MD.Id.front().second;
// Inferred modules must be submodules.
- if (!ActiveModule && !MD.Framework) {
+ if (!ActiveModule && !MD.getFramework()) {
Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
return;
}
if (ActiveModule) {
// Inferred modules must have umbrella directories.
- if (ActiveModule->IsAvailable && !ActiveModule->getEffectiveUmbrellaDir()) {
+ if (ActiveModule->getIsAvailable() &&
+ !ActiveModule->getEffectiveUmbrellaDir()) {
Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
return;
}
// Check for redefinition of an inferred module.
- if (ActiveModule->InferSubmodules) {
+ if (ActiveModule->getInferSubmodules()) {
Diags.Report(StarLoc, diag::err_mmap_inferred_redef);
if (ActiveModule->InferredSubmoduleLoc.isValid())
Diags.Report(ActiveModule->InferredSubmoduleLoc,
@@ -2358,24 +2364,24 @@ void ModuleMapLoader::handleInferredModuleDecl(
}
// Check for the 'framework' keyword, which is not permitted here.
- if (MD.Framework) {
+ if (MD.getFramework()) {
Diags.Report(StarLoc, diag::err_mmap_inferred_framework_submodule);
return;
}
- } else if (MD.Explicit) {
+ } else if (MD.getExplicit()) {
Diags.Report(StarLoc, diag::err_mmap_explicit_inferred_framework);
return;
}
if (ActiveModule) {
// Note that we have an inferred submodule.
- ActiveModule->InferSubmodules = true;
+ ActiveModule->setInferSubmodules(true);
ActiveModule->InferredSubmoduleLoc = StarLoc;
- ActiveModule->InferExplicitSubmodules = MD.Explicit;
+ ActiveModule->setInferExplicitSubmodules(MD.getExplicit());
} else {
// We'll be inferring framework modules for this directory.
auto &InfDir = Map.InferredDirectories[Directory];
- InfDir.InferModules = true;
+ InfDir.setInferModules(true);
InfDir.Attrs = MD.Attrs;
InfDir.ModuleMapFID = ModuleMapFID;
// FIXME: Handle the 'framework' keyword.
@@ -2412,7 +2418,7 @@ void ModuleMapLoader::handleInferredModuleDecl(
}
if (ED.Wildcard && ED.Id.size() == 0)
- ActiveModule->InferExportWildcard = true;
+ ActiveModule->setInferExportWildcard(true);
else
Diags.Report(ED.Id.front().second,
diag::err_mmap_expected_export_wildcard);
diff --git a/clang/lib/Lex/ModuleMapFile.cpp b/clang/lib/Lex/ModuleMapFile.cpp
index 4ca33cb86ddd3..0fc6f81d09598 100644
--- a/clang/lib/Lex/ModuleMapFile.cpp
+++ b/clang/lib/Lex/ModuleMapFile.cpp
@@ -122,13 +122,13 @@ struct ModuleMapFileParser {
SourceLocation consumeToken();
void skipUntil(MMToken::TokenKind K);
- bool parseModuleId(ModuleId &Id);
+ template <typename ModuleIdT> bool parseModuleId(ModuleIdT &Id);
bool parseOptionalAttributes(ModuleAttributes &Attrs);
SourceLocation getLocation() const { return Tok.getLocation(); };
};
-std::string formatModuleId(const ModuleId &Id) {
+std::string formatModuleId(llvm::ArrayRef<ModuleId::value_type> Id) {
std::string result;
{
llvm::raw_string_ostream OS(result);
@@ -253,13 +253,13 @@ std::optional<ModuleDecl> ModuleMapFileParser::parseModuleDecl(bool TopLevel) {
ModuleDecl MDecl;
SourceLocation ExplicitLoc;
- MDecl.Explicit = false;
- MDecl.Framework = false;
+ MDecl.setExplicit(false);
+ MDecl.setFramework(false);
// Parse 'explicit' keyword, if present.
if (Tok.is(MMToken::ExplicitKeyword)) {
MDecl.Location = ExplicitLoc = consumeToken();
- MDecl.Explicit = true;
+ MDecl.setExplicit(true);
}
// Parse 'framework' keyword, if present.
@@ -267,7 +267,7 @@ std::optional<ModuleDecl> ModuleMapFileParser::parseModuleDecl(bool TopLevel) {
SourceLocation FrameworkLoc = consumeToken();
if (!MDecl.Location.isValid())
MDecl.Location = FrameworkLoc;
- MDecl.Framework = true;
+ MDecl.setFramework(true);
}
// Parse 'module' keyword.
@@ -286,7 +286,7 @@ std::optional<ModuleDecl> ModuleMapFileParser::parseModuleDecl(bool TopLevel) {
if (Tok.is(MMToken::Star)) {
SourceLocation StarLoc = consumeToken();
MDecl.Id.push_back({"*", StarLoc});
- if (TopLevel && !MDecl.Framework) {
+ if (TopLevel && !MDecl.getFramework()) {
Diags.Report(StarLoc, diag::err_mmap_top_level_inferred_submodule);
HadError = true;
return std::nullopt;
@@ -305,10 +305,10 @@ std::optional<ModuleDecl> ModuleMapFileParser::parseModuleDecl(bool TopLevel) {
HadError = true;
}
- } else if (MDecl.Id.size() == 1 && MDecl.Explicit) {
+ } else if (MDecl.Id.size() == 1 && MDecl.getExplicit()) {
// Top-level modules can't be explicit.
Diags.Report(ExplicitLoc, diag::err_mmap_explicit_top_level);
- MDecl.Explicit = false;
+ MDecl.setExplicit(false);
HadError = true;
}
}
@@ -1032,7 +1032,8 @@ void ModuleMapFileParser::skipUntil(MMToken::TokenKind K) {
/// identifier '.' module-id
///
/// \returns true if an error occurred, false otherwise.
-bool ModuleMapFileParser::parseModuleId(ModuleId &Id) {
+template <typename ModuleIdT>
+bool ModuleMapFileParser::parseModuleId(ModuleIdT &Id) {
Id.clear();
do {
if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 3d991c411378e..3d3b7325b9588 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -50,6 +50,7 @@
#include <cassert>
#include <cstddef>
#include <cstring>
+#include <memory>
#include <optional>
#include <string>
#include <utility>
@@ -566,9 +567,16 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
// SkipExcludedConditionalBlock() recursively, SkippingRangeStateTy should
// change to do a second lookup in endLexPass function instead of reusing the
// lookup pointer.
- assert(!SkippingExcludedConditionalBlock &&
+ assert(!getSkippingExcludedConditionalBlock() &&
"calling SkipExcludedConditionalBlock recursively");
- llvm::SaveAndRestore SARSkipping(SkippingExcludedConditionalBlock, true);
+ auto SARSkipping = [PackedFlagOwner = this] {
+ const bool PackedFlagOld =
+ PackedFlagOwner->getSkippingExcludedConditionalBlock();
+ PackedFlagOwner->setSkippingExcludedConditionalBlock(true);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setSkippingExcludedConditionalBlock(PackedFlagOld);
+ });
+ }();
++NumSkipped;
assert(!CurTokenLexer && "Conditional PP block cannot appear in a macro!");
@@ -583,7 +591,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
// Enter raw mode to disable identifier lookup (and thus macro expansion),
// disabling warnings, etc.
- CurPPLexer->LexingRawMode = true;
+ CurPPLexer->setLexingRawMode(true);
Token Tok;
SourceLocation endLoc;
@@ -672,19 +680,24 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
if (II->getName()[0] == 'm') { // module
// HandleModuleContextualKeyword changes the lexer state, so we need
// to save RawLexingMode
- llvm::SaveAndRestore RestoreLexingRawMode(CurPPLexer->LexingRawMode,
- false);
+ auto RestoreLexingRawMode = [PackedFlagOwner_ = CurPPLexer] {
+ const bool PackedFlagOld_ = PackedFlagOwner_->getLexingRawMode();
+ PackedFlagOwner_->setLexingRawMode(false);
+ return llvm::scope_exit([PackedFlagOwner_, PackedFlagOld_] {
+ PackedFlagOwner_->setLexingRawMode(PackedFlagOld_);
+ });
+ }();
if (HandleModuleContextualKeyword(Tok)) {
// We just parsed a # character at the start of a line, so we're
// in directive mode. Tell the lexer this so any newlines we see
// will be converted into an EOD token (this terminates the
// macro).
- CurPPLexer->ParsingPreprocessorDirective = true;
+ CurPPLexer->setParsingPreprocessorDirectiveFlag(true);
SourceLocation StartLoc = Tok.getLocation();
SourceLocation End = DiscardUntilEndOfDirective().getEnd();
Diag(StartLoc, diag::err_pp_cond_span_module_decl)
<< SourceRange(StartLoc, End);
- CurPPLexer->ParsingPreprocessorDirective = false;
+ CurPPLexer->setParsingPreprocessorDirectiveFlag(false);
// Restore comment saving mode.
if (CurLexer)
CurLexer->resetExtendedTokenMode();
@@ -718,7 +731,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
// We just parsed a # character at the start of a line, so we're in
// directive mode. Tell the lexer this so any newlines we see will be
// converted into an EOD token (this terminates the macro).
- CurPPLexer->ParsingPreprocessorDirective = true;
+ CurPPLexer->setParsingPreprocessorDirectiveFlag(true);
if (CurLexer) CurLexer->SetKeepWhitespaceMode(false);
assert(Tok.is(tok::hash));
@@ -731,7 +744,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
// If this isn't an identifier directive (e.g. is "# 1\n" or "#\n", or
// something bogus), skip it.
if (Tok.isNot(tok::raw_identifier)) {
- CurPPLexer->ParsingPreprocessorDirective = false;
+ CurPPLexer->setParsingPreprocessorDirectiveFlag(false);
// Restore comment saving mode.
if (CurLexer) CurLexer->resetExtendedTokenMode();
continue;
@@ -747,7 +760,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
char FirstChar = RI[0];
if (FirstChar >= 'a' && FirstChar <= 'z' &&
FirstChar != 'i' && FirstChar != 'e') {
- CurPPLexer->ParsingPreprocessorDirective = false;
+ CurPPLexer->setParsingPreprocessorDirectiveFlag(false);
// Restore comment saving mode.
if (CurLexer) CurLexer->resetExtendedTokenMode();
continue;
@@ -764,7 +777,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
std::string DirectiveStr = getSpelling(Tok);
size_t IdLen = DirectiveStr.size();
if (IdLen >= 20) {
- CurPPLexer->ParsingPreprocessorDirective = false;
+ CurPPLexer->setParsingPreprocessorDirectiveFlag(false);
// Restore comment saving mode.
if (CurLexer) CurLexer->resetExtendedTokenMode();
continue;
@@ -801,9 +814,9 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
SkippingRangeState.endLexPass(Hashptr);
// Restore the value of LexingRawMode so that trailing comments
// are handled correctly, if we've reached the outermost block.
- CurPPLexer->LexingRawMode = false;
+ CurPPLexer->setLexingRawMode(false);
endLoc = CheckEndOfDirective("endif");
- CurPPLexer->LexingRawMode = true;
+ CurPPLexer->setLexingRawMode(true);
if (Callbacks)
Callbacks->Endif(Tok.getLocation(), CondInfo.IfLoc);
break;
@@ -832,9 +845,9 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
CondInfo.FoundNonSkip = true;
// Restore the value of LexingRawMode so that trailing comments
// are handled correctly.
- CurPPLexer->LexingRawMode = false;
+ CurPPLexer->setLexingRawMode(false);
endLoc = CheckEndOfDirective("else");
- CurPPLexer->LexingRawMode = true;
+ CurPPLexer->setLexingRawMode(true);
if (Callbacks)
Callbacks->Else(Tok.getLocation(), CondInfo.IfLoc);
break;
@@ -862,15 +875,16 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
} else {
// Restore the value of LexingRawMode so that identifiers are
// looked up, etc, inside the #elif expression.
- assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
- CurPPLexer->LexingRawMode = false;
+ assert(CurPPLexer->getLexingRawMode() &&
+ "We have to be skipping here!");
+ CurPPLexer->setLexingRawMode(false);
IdentifierInfo *IfNDefMacro = nullptr;
DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
// Stop if Lexer became invalid after hitting code completion token.
if (!CurPPLexer)
return;
const bool CondValue = DER.Conditional;
- CurPPLexer->LexingRawMode = true;
+ CurPPLexer->setLexingRawMode(true);
if (Callbacks) {
Callbacks->Elif(
Tok.getLocation(), DER.ExprRange,
@@ -914,11 +928,12 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
} else {
// Restore the value of LexingRawMode so that identifiers are
// looked up, etc, inside the #elif[n]def expression.
- assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
- CurPPLexer->LexingRawMode = false;
+ assert(CurPPLexer->getLexingRawMode() &&
+ "We have to be skipping here!");
+ CurPPLexer->setLexingRawMode(false);
Token MacroNameTok;
ReadMacroName(MacroNameTok);
- CurPPLexer->LexingRawMode = true;
+ CurPPLexer->setLexingRawMode(true);
// If the macro name token is tok::eod, there was an error that was
// already reported.
@@ -958,7 +973,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
SuggestTypoedDirective(Tok, Directive);
}
- CurPPLexer->ParsingPreprocessorDirective = false;
+ CurPPLexer->setParsingPreprocessorDirectiveFlag(false);
// Restore comment saving mode.
if (CurLexer) CurLexer->resetExtendedTokenMode();
}
@@ -966,7 +981,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
// Finally, if we are out of the conditional (saw an #endif or ran off the end
// of the file, just stop skipping and return to lexing whatever came after
// the #if block.
- CurPPLexer->LexingRawMode = false;
+ CurPPLexer->setLexingRawMode(false);
// The last skipped range isn't actually skipped yet if it's truncated
// by the end of the preamble; we'll resume parsing after the preamble.
@@ -1111,7 +1126,7 @@ OptionalFileEntryRef Preprocessor::LookupFile(
? HeaderInfo.getModuleMap().getBuiltinDir()
: MainFileDir;
Includers.push_back(std::make_pair(std::nullopt, *IncludeDir));
- BuildSystemModule = getCurrentModule()->IsSystem;
+ BuildSystemModule = getCurrentModule()->getIsSystem();
} else if ((FileEnt = SourceMgr.getFileEntryRefForID(
SourceMgr.getMainFileID()))) {
auto CWD = FileMgr.getOptionalDirectoryRef(".");
@@ -1297,11 +1312,12 @@ void Preprocessor::HandleSkippedDirectiveWhileUsingPCH(Token &Result,
return HandleDefineDirective(Result,
/*ImmediatelyAfterHeaderGuard=*/false);
}
- if (SkippingUntilPCHThroughHeader &&
+ if (getSkippingUntilPCHThroughHeader() &&
II->getPPKeywordID() == tok::pp_include) {
return HandleIncludeDirective(HashLoc, Result);
}
- if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
+ if (getSkippingUntilPragmaHdrStop() &&
+ II->getPPKeywordID() == tok::pp_pragma) {
Lex(Result);
auto *II = Result.getIdentifierInfo();
if (II && II->getName() == "hdrstop")
@@ -1321,7 +1337,7 @@ void Preprocessor::HandleDirective(Token &Result) {
// We just parsed a # or @ character at the start of a line, so we're in
// directive mode. Tell the lexer this so any newlines we see will be
// converted into an EOD token (which terminates the directive).
- CurPPLexer->ParsingPreprocessorDirective = true;
+ CurPPLexer->setParsingPreprocessorDirectiveFlag(true);
if (CurLexer) CurLexer->SetKeepWhitespaceMode(false);
bool ImmediatelyAfterTopLevelIfndef =
@@ -1381,7 +1397,7 @@ void Preprocessor::HandleDirective(Token &Result) {
// and reset to previous state when returning from this function.
ResetMacroExpansionHelper helper(this);
- if (SkippingUntilPCHThroughHeader || SkippingUntilPragmaHdrStop)
+ if (getSkippingUntilPCHThroughHeader() || getSkippingUntilPragmaHdrStop())
return HandleSkippedDirectiveWhileUsingPCH(Result,
Introducer.getLocation());
@@ -2432,9 +2448,9 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
IsFrameworkFound, IsImportDecl, IsMapped, LookupFrom, LookupFromFile,
LookupFilename, RelativePath, SearchPath, SuggestedModule, isAngled);
- if (usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) {
+ if (usingPCHWithThroughHeader() && getSkippingUntilPCHThroughHeader()) {
if (File && isPCHThroughHeader(&File->getFileEntry()))
- SkippingUntilPCHThroughHeader = false;
+ setSkippingUntilPCHThroughHeader(false);
return {ImportAction::None};
}
@@ -2462,7 +2478,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
// If we've reached the max allowed include depth, it is usually due to an
// include cycle. Don't enter already processed files again as it can lead to
// reaching the max allowed include depth again.
- if (Action == Enter && HasReachedMaxIncludeDepth && File &&
+ if (Action == Enter && getHasReachedMaxIncludeDepth() && File &&
alreadyIncluded(*File))
Action = IncludeLimitReached;
@@ -2783,7 +2799,7 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
// Check that we don't have infinite #include recursion.
if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
Diag(FilenameTok, diag::err_pp_include_too_deep);
- HasReachedMaxIncludeDepth = true;
+ setHasReachedMaxIncludeDepth(true);
return {ImportAction::None};
}
@@ -3080,7 +3096,7 @@ MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
// Ensure we consume the rest of the macro body if errors occur.
llvm::scope_exit _([&]() {
// The flag indicates if we are still waiting for 'eod'.
- if (CurLexer->ParsingPreprocessorDirective)
+ if (CurLexer->getParsingPreprocessorDirectiveFlag())
DiscardUntilEndOfDirective();
});
@@ -3351,7 +3367,7 @@ void Preprocessor::HandleDefineDirective(
}
// When skipping just warn about macros that do not match.
- if (SkippingUntilPCHThroughHeader) {
+ if (getSkippingUntilPCHThroughHeader()) {
const MacroInfo *OtherMI = getMacroInfo(MacroNameTok.getIdentifierInfo());
if (!OtherMI || !MI->isIdenticalTo(*OtherMI, *this,
/*Syntactic=*/LangOpts.MicrosoftExt))
@@ -3653,7 +3669,7 @@ void Preprocessor::HandleEndifDirective(Token &EndifToken) {
if (CurPPLexer->getConditionalStackDepth() == 0)
CurPPLexer->MIOpt.ExitTopLevelConditional();
- assert(!CondInfo.WasSkipping && !CurPPLexer->LexingRawMode &&
+ assert(!CondInfo.WasSkipping && !CurPPLexer->getLexingRawMode() &&
"This code should only be reachable in the non-skipping case!");
if (Callbacks)
@@ -4204,8 +4220,13 @@ void Preprocessor::HandleEmbedDirective(SourceLocation HashLoc,
/// lexed module name are replaced by annot_module_name token.
void Preprocessor::HandleCXXImportDirective(Token ImportTok) {
assert(getLangOpts().CPlusPlusModules && ImportTok.is(tok::kw_import));
- llvm::SaveAndRestore<bool> SaveImportingCXXModules(
- this->ImportingCXXNamedModules, true);
+ auto SaveImportingCXXModules = [PackedFlagOwner = this] {
+ const bool PackedFlagOld = PackedFlagOwner->getImportingCXXNamedModules();
+ PackedFlagOwner->setImportingCXXNamedModules(true);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setImportingCXXNamedModules(PackedFlagOld);
+ });
+ }();
Token Tok;
if (LexHeaderName(Tok)) {
@@ -4423,7 +4444,7 @@ void Preprocessor::HandleCXXModuleDirective(Token ModuleTok) {
bool IsGMFIntroducer = DirToks.size() == 2 && DirToks[0].is(tok::kw_module) &&
DirToks[1].is(tok::semi);
- bool IsSynthesizedGMF = IsGMFIntroducer && HasSynthesizedGMF &&
+ bool IsSynthesizedGMF = IsGMFIntroducer && getHasSynthesizedGMF() &&
CurPPLexer->getFileID() == getPredefinesFileID();
if (!IncludeMacroStack.empty() && !IsSynthesizedGMF) {
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index eb614cba959a4..0244f62f8d9e1 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -30,11 +30,13 @@
#include "clang/Lex/Token.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include <cassert>
+#include <memory>
using namespace clang;
@@ -885,7 +887,13 @@ Preprocessor::DirectiveEvalResult
Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro,
Token &Tok, bool &EvaluatedDefined,
bool CheckForEoD) {
- SaveAndRestore PPDir(ParsingIfOrElifDirective, true);
+ auto PPDir = [PackedFlagOwner = this] {
+ const bool PackedFlagOld = PackedFlagOwner->getParsingIfOrElifDirective();
+ PackedFlagOwner->setParsingIfOrElifDirective(true);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setParsingIfOrElifDirective(PackedFlagOld);
+ });
+ }();
// Save the current state of 'DisableMacroExpansion' and reset it to false. If
// 'DisableMacroExpansion' is true, then we must be in a macro argument list
// in which case a directive is undefined behavior. We want macros to be able
diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
index 552902e70f094..0dd9453939474 100644
--- a/clang/lib/Lex/PPLexerChange.cpp
+++ b/clang/lib/Lex/PPLexerChange.cpp
@@ -654,9 +654,9 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
// mode (#if COMMENT) in which case we have to return it to that mode and
// return EOD.
FoundLexer = ISI.ThePPLexer;
- FoundLexer->LexingRawMode = true;
- LexerWasInPPMode = FoundLexer->ParsingPreprocessorDirective;
- FoundLexer->ParsingPreprocessorDirective = true;
+ FoundLexer->setLexingRawMode(true);
+ LexerWasInPPMode = FoundLexer->getParsingPreprocessorDirectiveFlag();
+ FoundLexer->setParsingPreprocessorDirectiveFlag(true);
break;
}
@@ -678,14 +678,14 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
if (Tok.is(tok::eod)) {
assert(FoundLexer && "Can't get end of line without an active lexer");
// Restore the lexer back to normal mode instead of raw mode.
- FoundLexer->LexingRawMode = false;
+ FoundLexer->setLexingRawMode(false);
// If the lexer was already in preprocessor mode, just return the EOD token
// to finish the preprocessor line.
if (LexerWasInPPMode) return;
// Otherwise, switch out of PP mode and return the next lexed token.
- FoundLexer->ParsingPreprocessorDirective = false;
+ FoundLexer->setParsingPreprocessorDirectiveFlag(false);
return Lex(Tok);
}
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index f55e9196bcd61..2f1d6ae13f7df 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -240,7 +240,7 @@ void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II,
if (MI && NewMI != MI &&
!MI->isIdenticalTo(*NewMI, *this, /*Syntactically=*/true))
IsAmbiguous = true;
- IsSystemMacro &= Active->getOwningModule()->IsSystem ||
+ IsSystemMacro &= Active->getOwningModule()->getIsSystem() ||
SourceMgr.isInSystemHeader(NewMI->getDefinitionLoc());
MI = NewMI;
}
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index 078842ab08c5e..61f3526923620 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -36,6 +36,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -130,19 +131,24 @@ namespace {
// and return them to the stream to be read later.
// Currently used when reading _Pragma/__pragma directives.
struct TokenCollector {
+ TokenCollector(Preprocessor &Self, bool Collect, Token &Tok)
+ : Self(Self),
+ Tokens(decltype(this->Tokens)::withFlags(unsigned(Collect))), Tok(Tok) {
+ }
Preprocessor &Self;
- bool Collect;
- SmallVector<Token, 3> Tokens;
+ bool getCollect() const { return Tokens.getFlag(0); }
+ void setCollect(bool Value) { Tokens.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<Token, 3> Tokens;
Token &Tok;
void lex() {
- if (Collect)
+ if (getCollect())
Tokens.push_back(Tok);
Self.Lex(Tok);
}
void revert() {
- assert(Collect && "did not collect tokens");
+ assert(getCollect() && "did not collect tokens");
assert(!Tokens.empty() && "collected unexpected number of tokens");
// Push the ( "string" ) tokens into the token stream.
@@ -175,8 +181,8 @@ void Preprocessor::HandlePragmaDirective(PragmaIntroducer Introducer) {
PragmaHandlers->HandlePragma(*this, Introducer, Tok);
// If the pragma handler didn't read the rest of the line, consume it now.
- if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective())
- || (CurPPLexer && CurPPLexer->ParsingPreprocessorDirective))
+ if ((CurTokenLexer && CurTokenLexer->isParsingPreprocessorDirective()) ||
+ (CurPPLexer && CurPPLexer->getParsingPreprocessorDirectiveFlag()))
DiscardUntilEndOfDirective();
}
@@ -204,7 +210,7 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
// In Case #2, we check the syntax now, but then put the tokens back into the
// token stream for later consumption.
- TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};
+ TokenCollector Toks(*this, getInMacroArgPreExpansion(), Tok);
// Remember the pragma token location.
SourceLocation PragmaLoc = Tok.getLocation();
@@ -252,7 +258,7 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
}
// If we're expanding a macro argument, put the tokens back.
- if (InMacroArgPreExpansion) {
+ if (getInMacroArgPreExpansion()) {
Toks.revert();
return;
}
@@ -355,7 +361,7 @@ void clang::prepare_PragmaString(SmallVectorImpl<char> &StrVal) {
void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
// During macro pre-expansion, check the syntax now but put the tokens back
// into the token stream for later consumption. Same as Handle_Pragma.
- TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};
+ TokenCollector Toks(*this, getInMacroArgPreExpansion(), Tok);
// Remember the pragma token location.
SourceLocation PragmaLoc = Tok.getLocation();
@@ -386,7 +392,7 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
}
// If we're expanding a macro argument, put the tokens back.
- if (InMacroArgPreExpansion) {
+ if (getInMacroArgPreExpansion()) {
Toks.revert();
return;
}
@@ -445,9 +451,11 @@ void Preprocessor::HandlePragmaPoison() {
// This avoids errors on code like:
// #pragma GCC poison X
// #pragma GCC poison X
- if (CurPPLexer) CurPPLexer->LexingRawMode = true;
+ if (CurPPLexer)
+ CurPPLexer->setLexingRawMode(true);
LexUnexpandedToken(Tok);
- if (CurPPLexer) CurPPLexer->LexingRawMode = false;
+ if (CurPPLexer)
+ CurPPLexer->setLexingRawMode(false);
// If we reached the end of line, we're done.
if (Tok.is(tok::eod)) return;
@@ -822,7 +830,7 @@ void Preprocessor::HandlePragmaModuleBuild(Token &Tok) {
DiscardUntilEndOfDirective();
}
- CurLexer->LexingRawMode = true;
+ CurLexer->setLexingRawMode(true);
auto TryConsumeIdentifier = [&](StringRef Ident) -> bool {
if (Tok.getKind() != tok::raw_identifier ||
@@ -852,7 +860,7 @@ void Preprocessor::HandlePragmaModuleBuild(Token &Tok) {
// We hit something directive-shaped; check to see if this is the end
// of the module build.
- CurLexer->ParsingPreprocessorDirective = true;
+ CurLexer->setParsingPreprocessorDirectiveFlag(true);
CurLexer->Lex(Tok);
if (TryConsumeIdentifier("pragma") && TryConsumeIdentifier("clang") &&
TryConsumeIdentifier("module")) {
@@ -870,7 +878,7 @@ void Preprocessor::HandlePragmaModuleBuild(Token &Tok) {
}
}
- CurLexer->LexingRawMode = false;
+ CurLexer->setLexingRawMode(false);
// Load the extracted text as a preprocessed module.
assert(CurLexer->getBuffer().begin() <= Start &&
@@ -910,7 +918,7 @@ void Preprocessor::HandlePragmaHdrstop(Token &Tok) {
CurLexer->cutOffLexing();
}
if (usingPCHWithPragmaHdrStop())
- SkippingUntilPragmaHdrStop = false;
+ setSkippingUntilPragmaHdrStop(false);
}
bool Preprocessor::isPragmaSetPPStateMacro(IdentifierInfo *MacroName) {
@@ -1206,7 +1214,7 @@ struct PragmaDebugHandler : public PragmaHandler {
llvm::errs() << "\n";
}
for (Module *Sub : M->submodules()) {
- if (!VisibleOnly || ImportLoc.isInvalid() || Sub->IsExplicit)
+ if (!VisibleOnly || ImportLoc.isInvalid() || Sub->getIsExplicit())
visit(Sub, VisibleOnly);
}
}
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 84907adc5d744..96b77d3f80dca 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -103,7 +103,7 @@ Preprocessor::Preprocessor(const PreprocessorOptions &PPOpts,
OwnsHeaderSearch = OwnsHeaders;
// Only record check points if we might highlight diagnostic snippets.
- RecordCheckPoints = getDiagnostics().getShowColors();
+ setRecordCheckPoints(getDiagnostics().getShowColors());
// Default to discarding comments.
KeepComments = false;
@@ -115,11 +115,11 @@ Preprocessor::Preprocessor(const PreprocessorOptions &PPOpts,
MacroExpansionInDirectivesOverride = false;
InMacroArgs = false;
ArgMacro = nullptr;
- InMacroArgPreExpansion = false;
+ setInMacroArgPreExpansion(false);
NumCachedTokenLexers = 0;
PragmasEnabled = true;
- ParsingIfOrElifDirective = false;
- PreprocessedOutput = false;
+ setParsingIfOrElifDirective(false);
+ setPreprocessedOutputFlag(false);
// We haven't read anything from the external source.
ReadMacrosFromExternalSource = false;
@@ -163,16 +163,16 @@ Preprocessor::Preprocessor(const PreprocessorOptions &PPOpts,
// Default incremental processing to -fincremental-extensions, clients can
// override with `enableIncrementalProcessing` if desired.
- IncrementalProcessing = LangOpts.IncrementalExtensions;
+ setIncrementalProcessing(LangOpts.IncrementalExtensions);
// If using a PCH where a #pragma hdrstop is expected, start skipping tokens.
if (usingPCHWithPragmaHdrStop())
- SkippingUntilPragmaHdrStop = true;
+ setSkippingUntilPragmaHdrStop(true);
// If using a PCH with a through header, start skipping tokens.
if (!this->PPOpts.PCHThroughHeader.empty() &&
!this->PPOpts.ImplicitPCHInclude.empty())
- SkippingUntilPCHThroughHeader = true;
+ setSkippingUntilPCHThroughHeader(true);
if (this->PPOpts.GeneratePreamble)
PreambleConditionalStack.startRecording();
@@ -626,9 +626,10 @@ void Preprocessor::EnterMainSourceFile() {
std::optional<StringRef> Input =
getSourceManager().getBufferDataOrNone(MainFileID);
if (!isPreprocessedModuleFile() && Input)
- MainFileIsPreprocessedModuleFile =
- clang::isPreprocessedModuleFile(*Input);
- if (Input && !MainFileIsPreprocessedModuleFile && hasDeferredGMFInputs())
+ setMainFileIsPreprocessedModuleFile(
+ clang::isPreprocessedModuleFile(*Input));
+ if (Input && !getMainFileIsPreprocessedModuleFile() &&
+ hasDeferredGMFInputs())
MainFileModuleUnitKind = scanInputForCXX20ModuleUnit(*Input);
auto Tracer = std::make_unique<NoTrivialPPDirectiveTracer>(*this);
DirTracer = Tracer.get();
@@ -645,7 +646,7 @@ void Preprocessor::EnterMainSourceFile() {
// GMF, synthesize the introducer before the main file and use the same
// deferred-input path.
if (hasDeferredGMFInputs()) {
- if (PredefinesWereReplaced) {
+ if (getPredefinesWereReplaced()) {
// Loading an implicit PCH replaces Predefines with the directives
// suggested by ASTReader. For a module unit, those are the only implicit
// inputs that still need to be processed in the GMF.
@@ -661,7 +662,7 @@ void Preprocessor::EnterMainSourceFile() {
if (MainFileModuleUnitKind ==
ModuleUnitKind::NamedModuleWithoutGlobalModuleFragment) {
Predefines += "# 1 \"<implicit-global-module-fragment>\" 1\nmodule;\n";
- HasSynthesizedGMF = true;
+ setHasSynthesizedGMF(true);
} else if (MainFileModuleUnitKind == ModuleUnitKind::NotModuleUnit) {
DeferredGMFInputs.clear();
}
@@ -697,8 +698,8 @@ void Preprocessor::EnterMainSourceFile() {
}
// Skip tokens from the Predefines and if needed the main file.
- if ((usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) ||
- (usingPCHWithPragmaHdrStop() && SkippingUntilPragmaHdrStop))
+ if ((usingPCHWithThroughHeader() && getSkippingUntilPCHThroughHeader()) ||
+ (usingPCHWithPragmaHdrStop() && getSkippingUntilPragmaHdrStop()))
SkipTokensWhileUsingPCH();
}
@@ -753,8 +754,8 @@ bool Preprocessor::usingPCHWithPragmaHdrStop() {
/// main file is reached, it's a fatal error.
void Preprocessor::SkipTokensWhileUsingPCH() {
bool ReachedMainFileEOF = false;
- bool UsingPCHThroughHeader = SkippingUntilPCHThroughHeader;
- bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop;
+ bool UsingPCHThroughHeader = getSkippingUntilPCHThroughHeader();
+ bool UsingPragmaHdrStop = getSkippingUntilPragmaHdrStop();
Token Tok;
while (true) {
bool InPredefines =
@@ -764,9 +765,9 @@ void Preprocessor::SkipTokensWhileUsingPCH() {
ReachedMainFileEOF = true;
break;
}
- if (UsingPCHThroughHeader && !SkippingUntilPCHThroughHeader)
+ if (UsingPCHThroughHeader && !getSkippingUntilPCHThroughHeader())
break;
- if (UsingPragmaHdrStop && !SkippingUntilPragmaHdrStop)
+ if (UsingPragmaHdrStop && !getSkippingUntilPragmaHdrStop())
break;
}
if (ReachedMainFileEOF) {
@@ -966,7 +967,7 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
// Handle module contextual keywords.
if (getLangOpts().CPlusPlusModules && CurLexer &&
!CurLexer->isLexingRawMode() && !CurLexer->isPragmaLexer() &&
- !CurLexer->ParsingPreprocessorDirective &&
+ !CurLexer->getParsingPreprocessorDirectiveFlag() &&
Identifier.isModuleContextualKeyword() &&
HandleModuleContextualKeyword(Identifier)) {
HandleDirective(Identifier);
@@ -1068,7 +1069,7 @@ void Preprocessor::Lex(Token &Result) {
}
}
- if (RecordCheckPoints && CurLexer &&
+ if (getRecordCheckPoints() && CurLexer &&
++CheckPointCounter == CheckPointStepSize) {
CheckPoints[CurLexer->getFileID()].push_back(CurLexer->BufferPtr);
CheckPointCounter = 0;
@@ -1085,7 +1086,7 @@ void Preprocessor::Lex(Token &Result) {
if (LexLevel == 0 && !PendingDestroyLexers.empty())
PendingDestroyLexers.clear();
- if ((LexLevel == 0 || PreprocessToken) &&
+ if ((LexLevel == 0 || getPreprocessTokenFlag()) &&
!Result.getFlag(Token::IsReinjected)) {
if (LexLevel == 0)
++TokenCount;
@@ -1123,7 +1124,7 @@ bool Preprocessor::LexHeaderName(Token &FilenameTok, bool AllowMacroExpansion) {
if (CurPPLexer) {
// Avoid nested header-name lexing when macro expansion recurses
// __has_include(__has_include))
- if (CurPPLexer->ParsingFilename)
+ if (CurPPLexer->getParsingFilename())
LexUnexpandedToken(FilenameTok);
else
CurPPLexer->LexIncludeFilename(FilenameTok);
@@ -1406,8 +1407,14 @@ bool Preprocessor::HandleModuleContextualKeyword(Token &Result) {
assert(CurPPLexer && "CurPPLexer must not be null");
- llvm::SaveAndRestore<bool> SavedParsingPreprocessorDirective(
- CurPPLexer->ParsingPreprocessorDirective, true);
+ auto SavedParsingPreprocessorDirective = [PackedFlagOwner_ = CurPPLexer] {
+ const bool PackedFlagOld_ =
+ PackedFlagOwner_->getParsingPreprocessorDirectiveFlag();
+ PackedFlagOwner_->setParsingPreprocessorDirectiveFlag(true);
+ return llvm::scope_exit([PackedFlagOwner_, PackedFlagOld_] {
+ PackedFlagOwner_->setParsingPreprocessorDirectiveFlag(PackedFlagOld_);
+ });
+ }();
if (II->isModuleKeyword()) {
if (auto NextTok = peekNextPPToken()) {
@@ -1423,8 +1430,13 @@ bool Preprocessor::HandleModuleContextualKeyword(Token &Result) {
}
if (II->isImportKeyword()) {
- llvm::SaveAndRestore<bool> SavedParsingFilename(CurPPLexer->ParsingFilename,
- true);
+ auto SavedParsingFilename = [PackedFlagOwner_ = CurPPLexer] {
+ const bool PackedFlagOld_ = PackedFlagOwner_->getParsingFilename();
+ PackedFlagOwner_->setParsingFilename(true);
+ return llvm::scope_exit([PackedFlagOwner_, PackedFlagOld_] {
+ PackedFlagOwner_->setParsingFilename(PackedFlagOld_);
+ });
+ }();
if (auto NextTok = peekNextPPToken()) {
if (NextTok->is(tok::raw_identifier))
LookUpIdentifierInfo(*NextTok);
diff --git a/clang/lib/Lex/PreprocessorLexer.cpp b/clang/lib/Lex/PreprocessorLexer.cpp
index 3f483c56f8b12..d3dc44b4befb1 100644
--- a/clang/lib/Lex/PreprocessorLexer.cpp
+++ b/clang/lib/Lex/PreprocessorLexer.cpp
@@ -29,19 +29,19 @@ PreprocessorLexer::PreprocessorLexer(Preprocessor *pp, FileID fid)
/// After the preprocessor has parsed a \#include, lex and
/// (potentially) macro expand the filename.
void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) {
- assert(ParsingFilename == false && "reentered LexIncludeFilename");
+ assert(getParsingFilename() == false && "reentered LexIncludeFilename");
// We are now parsing a filename!
- ParsingFilename = true;
+ setParsingFilename(true);
// Lex the filename.
- if (LexingRawMode)
+ if (getLexingRawMode())
IndirectLex(FilenameTok);
else
PP->Lex(FilenameTok);
// We should have obtained the filename now.
- ParsingFilename = false;
+ setParsingFilename(false);
}
/// getFileEntry - Return the FileEntry corresponding to this FileID. Like
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 6b478ec2e36f6..832030bbac9d8 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -134,7 +134,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
return FnD;
}
- if (SkipFunctionBodies && (!FnD || Actions.canSkipFunctionBody(FnD)) &&
+ if (getSkipFunctionBodies() && (!FnD || Actions.canSkipFunctionBody(FnD)) &&
trySkippingFunctionBody()) {
Actions.ActOnSkippedFunctionBody(FnD);
return FnD;
@@ -335,10 +335,10 @@ struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII {
ReenterClassScopeRAII(Parser &P, ParsingClass &Class)
: ReenterTemplateScopeRAII(P, Class.TagOrTemplate,
- /*Enter=*/!Class.TopLevelClass),
+ /*Enter=*/!Class.isTopLevelClass()),
Class(Class) {
// If this is the top-level class, we're still within its scope.
- if (Class.TopLevelClass)
+ if (Class.isTopLevelClass())
return;
// Re-enter the class scope itself.
@@ -347,7 +347,7 @@ struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII {
Class.TagOrTemplate);
}
~ReenterClassScopeRAII() {
- if (Class.TopLevelClass)
+ if (Class.isTopLevelClass())
return;
P.Actions.ActOnFinishDelayedMemberDeclarations(P.getCurScope(),
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 4024928718444..47fc609654320 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2701,7 +2701,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
ThisVarDecl->getType()->getCanonicalTypeInternal(),
ThisDecl->getLocation(), Exprs, T.getOpenLocation(),
/*Braced=*/false);
- CalledSignatureHelp = true;
+ setCalledSignatureHelp(true);
return PreferredType;
};
auto SetPreferredType = [&] {
@@ -2720,12 +2720,13 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
if (SawError) {
- if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
+ if (ThisVarDecl && PP.isCodeCompletionReached() &&
+ !getCalledSignatureHelp()) {
Actions.CodeCompletion().ProduceConstructorSignatureHelp(
ThisVarDecl->getType()->getCanonicalTypeInternal(),
ThisDecl->getLocation(), Exprs, T.getOpenLocation(),
/*Braced=*/false);
- CalledSignatureHelp = true;
+ setCalledSignatureHelp(true);
}
Actions.ActOnInitializerError(ThisDecl);
SkipUntil(tok::r_paren, StopAtSemi);
@@ -5265,7 +5266,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// Parse the fixed underlying type.
if (Tok.is(tok::colon) &&
- (!ParsingGenericAssociationType || IsCXXTypeAhead())) {
+ (!getParsingGenericAssociationType() || IsCXXTypeAhead())) {
// This might be an enum-base or part of some unrelated enclosing context.
//
// 'enum E : base' is permitted in two circumstances:
@@ -5295,7 +5296,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// not make sense as one. In C++11, it's an error if this happens.
if (getLangOpts().CPlusPlus11)
Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
- } else if (CanHaveEnumBase || !ColonIsSacred) {
+ } else if (CanHaveEnumBase || !getColonIsSacred()) {
SourceLocation ColonLoc = ConsumeToken();
// Parse a type-specifier-seq as a type. We can't just ParseTypeName here,
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 4cf445d68bdbe..379e846a7ae45 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1546,8 +1546,8 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
return true;
case tok::colon:
return CouldBeBitfield || // enum E { ... } : 2;
- ColonIsSacred ||
- ParsingGenericAssociationType; // _Generic(..., enum E : 2);
+ getColonIsSacred() ||
+ getParsingGenericAssociationType(); // _Generic(..., enum E : 2);
// Microsoft compatibility
case tok::kw___cdecl: // struct foo {...} __cdecl x;
case tok::kw___fastcall: // struct foo {...} __fastcall x;
@@ -2613,7 +2613,7 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
ParseTrailingRequiresClauseWithScope(DeclaratorInfo);
} else {
ParseOptionalCXX11VirtSpecifierSeq(
- VS, getCurrentClass().IsInterface,
+ VS, getCurrentClass().isInterface(),
DeclaratorInfo.getDeclSpec().getFriendSpecLoc());
if (!VS.isUnset())
MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
@@ -2642,7 +2642,7 @@ bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
// virt-specifier *after* the GNU attributes.
if (BitfieldSize.isUnset() && VS.isUnset()) {
ParseOptionalCXX11VirtSpecifierSeq(
- VS, getCurrentClass().IsInterface,
+ VS, getCurrentClass().isInterface(),
DeclaratorInfo.getDeclSpec().getFriendSpecLoc());
if (!VS.isUnset()) {
// If we saw any GNU-style attributes that are known to GCC followed by a
@@ -3355,8 +3355,11 @@ ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
// CWG2760
// Default member initializers used to initialize a base or member subobject
// [...] are considered to be part of the function body
- Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext =
- IsFieldInitialization;
+ [&] {
+ auto PackedFlagValue_ = IsFieldInitialization;
+ return Actions.ExprEvalContexts.back()
+ .setInImmediateEscalatingFunctionContext(PackedFlagValue_);
+ }();
if (TryConsumeToken(tok::equal, EqualLoc)) {
if (Tok.is(tok::kw_delete)) {
@@ -3588,7 +3591,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
NonNestedClass = false;
// The Microsoft extension __interface does not permit nested classes.
- if (getCurrentClass().IsInterface) {
+ if (getCurrentClass().isInterface()) {
Diag(RecordLoc, diag::err_invalid_member_in_interface)
<< /*ErrorType=*/6
<< (isa<NamedDecl>(TagDecl)
@@ -3952,14 +3955,14 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
Actions.CodeCompletion().ProduceCtorInitMemberSignatureHelp(
ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II,
T.getOpenLocation(), /*Braced=*/false);
- CalledSignatureHelp = true;
+ setCalledSignatureHelp(true);
return PreferredType;
};
if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] {
PreferredType.enterFunctionArgument(Tok.getLocation(),
RunSignatureHelp);
})) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ if (PP.isCodeCompletionReached() && !getCalledSignatureHelp())
RunSignatureHelp();
SkipUntil(tok::r_paren, StopAtSemi);
return true;
@@ -4276,7 +4279,7 @@ void Parser::PopParsingClass(Sema::ParsingClassState state) {
ParsingClass *Victim = ClassStack.top();
ClassStack.pop();
- if (Victim->TopLevelClass) {
+ if (Victim->isTopLevelClass()) {
// Deallocate all of the nested classes of this class,
// recursively: we don't need to keep any of this information.
DeallocateParsedClasses(Victim);
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index d42ffc2ccf0a6..b64b8e37ef3bd 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -146,7 +146,8 @@ ExprResult Parser::ParseArrayBoundExpression() {
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
// If we parse the bound of a VLA... we parse a non-constant
// constant-expression!
- Actions.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
+ Actions.ExprEvalContexts.back().setInConditionallyConstantEvaluateContext(
+ true);
// For a VLA type inside an unevaluated operator like:
//
// sizeof(typeof(*(int (*)[N])array))
@@ -164,7 +165,7 @@ ExprResult Parser::ParseArrayBoundExpression() {
Iter != Actions.ExprEvalContexts.rend(); ++Iter) {
if (!Iter->isUnevaluated())
break;
- Iter->InConditionallyConstantEvaluateContext = true;
+ Iter->setInConditionallyConstantEvaluateContext(true);
}
return ParseConstantExpressionInExprEvalContext(
TypoCorrectionTypeBehavior::AllowNonTypes);
@@ -173,7 +174,7 @@ ExprResult Parser::ParseArrayBoundExpression() {
ExprResult Parser::ParseCaseExpression(SourceLocation CaseLoc) {
EnterExpressionEvaluationContext ConstantEvaluated(
Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
- Actions.currentEvaluationContext().IsCaseExpr = true;
+ Actions.currentEvaluationContext().setIsCaseExpr(true);
ExprResult LHS(
ParseCastExpression(CastParseKind::AnyCastExpr, false,
@@ -921,7 +922,7 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand,
}
}
- else if ((!ColonIsSacred && Next.is(tok::colon)) ||
+ else if ((!getColonIsSacred() && Next.is(tok::colon)) ||
Next.isOneOf(tok::coloncolon, tok::less, tok::l_paren,
tok::l_brace)) {
// If TryAnnotateTypeOrScopeToken annotates the token, tail recurse.
@@ -1874,7 +1875,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
QualType PreferredType =
Actions.CodeCompletion().ProduceCallSignatureHelp(
LHS.get(), ArgExprs, PT.getOpenLocation());
- CalledSignatureHelp = true;
+ setCalledSignatureHelp(true);
return PreferredType;
};
bool ExpressionListIsInvalid = false;
@@ -1888,7 +1889,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// the CodeCompleteCall handler inside the parser. So call it here
// to make sure we get overload suggestions even when we are in the
// middle of a parameter.
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ if (PP.isCodeCompletionReached() && !getCalledSignatureHelp())
RunSignatureHelp();
}
}
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 3745ea53fc6d0..daa1bb331234f 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -422,8 +422,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
// If we get foo:bar, this is almost certainly a typo for foo::bar. Recover
// and emit a fixit hint for it.
- if (Next.is(tok::colon) && !ColonIsSacred &&
- !ParsingGenericAssociationType) {
+ if (Next.is(tok::colon) && !getColonIsSacred() &&
+ !getParsingGenericAssociationType()) {
if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, IdInfo,
EnteringContext) &&
// If the token after the colon isn't an identifier, it's still an
@@ -454,7 +454,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
return false;
}
- if (ColonIsSacred) {
+ if (getColonIsSacred()) {
const Token &Next2 = GetLookAheadToken(2);
if (Next2.is(tok::kw_private) || Next2.is(tok::kw_protected) ||
Next2.is(tok::kw_public) || Next2.is(tok::kw_virtual)) {
@@ -483,7 +483,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
SourceLocation ScopeBeginLoc = SS.getBeginLoc();
bool IsCorrectedToColon = false;
- bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;
+ bool *CorrectionFlagPtr =
+ getColonIsSacred() ? &IsCorrectedToColon : nullptr;
if (Actions.ActOnCXXNestedNameSpecifier(
getCurScope(), IdInfo, EnteringContext, SS, CorrectionFlagPtr,
OnlyNamespace)) {
@@ -1843,7 +1844,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
Actions.CodeCompletion().ProduceConstructorSignatureHelp(
TypeRep.get()->getCanonicalTypeInternal(), DS.getEndLoc(),
Exprs, T.getOpenLocation(), /*Braced=*/false);
- CalledSignatureHelp = true;
+ setCalledSignatureHelp(true);
return PreferredType;
};
@@ -1852,7 +1853,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
PreferredType.enterFunctionArgument(Tok.getLocation(),
RunSignatureHelp);
})) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ if (PP.isCodeCompletionReached() && !getCalledSignatureHelp())
RunSignatureHelp();
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
@@ -3050,14 +3051,14 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
DeclaratorInfo.getEndLoc(), ConstructorArgs,
ConstructorLParen,
/*Braced=*/false);
- CalledSignatureHelp = true;
+ setCalledSignatureHelp(true);
return PreferredType;
};
if (ParseExpressionList(ConstructorArgs, [&] {
PreferredType.enterFunctionArgument(Tok.getLocation(),
RunSignatureHelp);
})) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ if (PP.isCodeCompletionReached() && !getCalledSignatureHelp())
RunSignatureHelp();
SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError();
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index e63509147fc91..d2513f1d8e624 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -2026,7 +2026,7 @@ Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) {
}
Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
- if (!Finished) {
+ if (!getFinished()) {
finish(P.Tok.getLocation());
if (P.isEofOrEom()) {
P.Diag(P.Tok, diag::err_objc_missing_end)
@@ -2039,7 +2039,7 @@ Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
}
void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
- assert(!Finished);
+ assert(!getFinished());
P.Actions.ObjC().DefaultSynthesizeProperties(P.getCurScope(), Dcl,
AtEnd.getBegin());
for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
@@ -2048,7 +2048,7 @@ void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
P.Actions.ObjC().ActOnAtEnd(P.getCurScope(), AtEnd);
- if (HasCFunction)
+ if (getHasCFunction())
for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
false/*c-functions*/);
@@ -2064,7 +2064,7 @@ void Parser::ObjCImplParsingDataRAII::finish(SourceRange AtEnd) {
// (e.g. a nested @interface ended the @implementation early), so stop being
// the current @implementation now rather than in the destructor.
P.CurParsedObjCImpl = PrevParsedObjCImpl;
- Finished = true;
+ setFinished(true);
}
Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
@@ -2393,7 +2393,8 @@ Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
}
void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
- if (SkipFunctionBodies && (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
+ if (getSkipFunctionBodies() &&
+ (!MDecl || Actions.canSkipFunctionBody(MDecl)) &&
trySkippingFunctionBody()) {
Actions.ActOnSkippedFunctionBody(MDecl);
return;
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index eb9106b673045..4d57234e8512d 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -1239,13 +1239,14 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams(
OpenACCWaitParseInfo Info =
ParseOpenACCWaitArgument(ClauseLoc,
/*IsDirective=*/false);
- if (Info.Failed) {
+ if (Info.getFailed()) {
Parens.skipToEnd();
return OpenACCCanContinue();
}
- ParsedClause.setWaitDetails(Info.DevNumExpr, Info.QueuesLoc,
- std::move(Info.QueueIdExprs));
+ ParsedClause.setWaitDetails(
+ Info.DevNumExpr, Info.QueuesLoc,
+ SmallVector<Expr *>(std::move(Info.QueueIdExprs)));
break;
}
default:
@@ -1290,12 +1291,12 @@ Parser::ParseOpenACCWaitArgument(SourceLocation Loc, bool IsDirective) {
Loc);
if (Res.first.isInvalid() &&
Res.second == OpenACCParseCanContinue::Cannot) {
- Result.Failed = true;
+ Result.setFailed(true);
return Result;
}
if (ExpectAndConsume(tok::colon)) {
- Result.Failed = true;
+ Result.setFailed(true);
return Result;
}
@@ -1325,7 +1326,7 @@ Parser::ParseOpenACCWaitArgument(SourceLocation Loc, bool IsDirective) {
if (Res.first.isInvalid() &&
Res.second == OpenACCParseCanContinue::Cannot) {
- Result.Failed = true;
+ Result.setFailed(true);
return Result;
}
@@ -1334,7 +1335,7 @@ Parser::ParseOpenACCWaitArgument(SourceLocation Loc, bool IsDirective) {
while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
if (ExpectAndConsume(tok::comma)) {
- Result.Failed = true;
+ Result.setFailed(true);
return Result;
}
@@ -1346,7 +1347,7 @@ Parser::ParseOpenACCWaitArgument(SourceLocation Loc, bool IsDirective) {
if (Res.first.isInvalid() &&
Res.second == OpenACCParseCanContinue::Cannot) {
- Result.Failed = true;
+ Result.setFailed(true);
return Result;
}
@@ -1539,7 +1540,7 @@ Parser::ParseOpenACCDirective() {
case OpenACCDirectiveKind::Wait:
// OpenACC has an optional paren-wrapped 'wait-argument'.
WaitInfo = ParseOpenACCWaitArgument(DirLoc, /*IsDirective=*/true);
- if (WaitInfo.Failed)
+ if (WaitInfo.getFailed())
T.skipToEnd();
else
T.consumeClose();
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 95c26f35fff03..29c7520562b39 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -365,14 +365,14 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
Actions.CodeCompletion().ProduceConstructorSignatureHelp(
OmpPrivParm->getType()->getCanonicalTypeInternal(),
OmpPrivParm->getLocation(), Exprs, LParLoc, /*Braced=*/false);
- CalledSignatureHelp = true;
+ setCalledSignatureHelp(true);
return PreferredType;
};
if (ParseExpressionList(Exprs, [&] {
PreferredType.enterFunctionArgument(Tok.getLocation(),
RunSignatureHelp);
})) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ if (PP.isCodeCompletionReached() && !getCalledSignatureHelp())
RunSignatureHelp();
Actions.ActOnInitializerError(OmpPrivParm);
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
@@ -3895,7 +3895,7 @@ bool Parser::ParseOMPInteropInfo(OMPInteropInfo &InteropInfo,
if (FrExpr || !AttrExprs.empty())
InteropInfo.Prefs.emplace_back(FrExpr, AttrExprs);
- InteropInfo.HasPreferAttrs = true;
+ InteropInfo.setPreferAttrs(true);
} else {
// OMP 5.1: flat foreign-runtime-id (string or int). Stored as a
// pref-spec with Fr=expr and no attr() entries.
@@ -3943,8 +3943,8 @@ bool Parser::ParseOMPInteropInfo(OMPInteropInfo &InteropInfo,
// As of OpenMP 5.1,there are two interop-types, "target" and
// "targetsync". Either or both are allowed for a single interop.
- InteropInfo.IsTarget = IsTarget;
- InteropInfo.IsTargetSync = IsTargetSync;
+ InteropInfo.setIsTarget(IsTarget);
+ InteropInfo.setIsTargetSync(IsTargetSync);
return HasError;
}
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 14bea6a1a7948..4808206098d0b 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1944,8 +1944,8 @@ void Parser::ParseForRangeInitializerAfterColon(ForRangeInit &FRI,
// P2718R0 - Lifetime extension in range-based for loops.
if (getLangOpts().CPlusPlus23) {
auto &LastRecord = Actions.currentEvaluationContext();
- LastRecord.InLifetimeExtendingContext = true;
- LastRecord.RebuildDefaultArgOrDefaultInit = true;
+ LastRecord.setInLifetimeExtendingContext(true);
+ LastRecord.setRebuildDefaultArgOrDefaultInit(true);
}
if (FRI.ExpansionStmt) {
@@ -2620,7 +2620,7 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
}
bool Parser::trySkippingFunctionBody() {
- assert(SkipFunctionBodies &&
+ assert(getSkipFunctionBodies() &&
"Should only be called when SkipFunctionBodies is enabled");
if (!PP.isCodeCompletionEnabled()) {
SkipFunctionBody();
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index ef6920fdc485c..cdda54e59f63a 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1392,7 +1392,7 @@ bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
auto RunSignatureHelp = [&] {
if (!Template)
return QualType();
- CalledSignatureHelp = true;
+ setCalledSignatureHelp(true);
return Actions.CodeCompletion().ProduceTemplateArgumentSignatureHelp(
Template, TemplateArgs, OpenLoc);
};
@@ -1405,7 +1405,7 @@ bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);
if (Arg.isInvalid()) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ if (PP.isCodeCompletionReached() && !getCalledSignatureHelp())
RunSignatureHelp();
return true;
}
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index a4581538fbcec..0ed7acc16af59 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1573,7 +1573,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
// enum E : int { 4 }; // bit-field
// };
if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace)) {
- if (ParsingGenericAssociationType) {
+ if (getParsingGenericAssociationType()) {
RevertingTentativeParsingAction PA(*this);
ConsumeAnyToken(); // skip keyword
ConsumeBrace(); // skip l_brace
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index c5d6a17fbfcd3..fd612b2b99872 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -73,10 +73,9 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
: PP(pp),
PreferredType(&actions.getASTContext(), pp.isCodeCompletionEnabled()),
Actions(actions), Diags(PP.getDiagnostics()), StackHandler(Diags),
- GreaterThanIsOperator(true), ColonIsSacred(false),
- ParsingGenericAssociationType(false), InMessageExpression(false),
+ GreaterThanIsOperator(true), InMessageExpression(false),
ParsingInObjCContainer(false), TemplateParameterDepth(0) {
- SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
+ setSkipFunctionBodies(pp.isCodeCompletionEnabled() || skipFunctionBodies);
Tok = Token::createEof();
Actions.CurScope = nullptr;
NumCachedScopes = 0;
@@ -1263,7 +1262,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
D.complete(DP);
D.getMutableDeclSpec().abort();
- if (SkipFunctionBodies && (!DP || Actions.canSkipFunctionBody(DP)) &&
+ if (getSkipFunctionBodies() && (!DP || Actions.canSkipFunctionBody(DP)) &&
trySkippingFunctionBody()) {
BodyScope.Exit();
return Actions.ActOnSkippedFunctionBody(DP);
@@ -1294,7 +1293,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
if (FuncDecl) {
// Consume the tokens and store them for later parsing.
StashAwayMethodOrFunctionBodyTokens(FuncDecl);
- CurParsedObjCImpl->HasCFunction = true;
+ CurParsedObjCImpl->setHasCFunction(true);
return FuncDecl;
}
// FIXME: Should we really fall through here?
@@ -1397,7 +1396,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
ParseLexedAttributeList(*LateParsedAttrs, Res, /*EnterScope=*/false,
/*OnDefinition=*/true);
- if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) &&
+ if (getSkipFunctionBodies() && (!Res || Actions.canSkipFunctionBody(Res)) &&
trySkippingFunctionBody()) {
BodyScope.Exit();
Actions.ActOnSkippedFunctionBody(Res);
diff --git a/clang/lib/Sema/CoroutineStmtBuilder.h b/clang/lib/Sema/CoroutineStmtBuilder.h
index 42499a32fc167..7abc0541a9b38 100644
--- a/clang/lib/Sema/CoroutineStmtBuilder.h
+++ b/clang/lib/Sema/CoroutineStmtBuilder.h
@@ -18,6 +18,7 @@
#include "clang/AST/StmtCXX.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/SemaInternal.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace clang {
@@ -25,10 +26,11 @@ class CoroutineStmtBuilder : public CoroutineBodyStmt::CtorArgs {
Sema &S;
FunctionDecl &FD;
sema::FunctionScopeInfo &Fn;
- bool IsValid = true;
+ bool getIsValid() const { return !ParamMovesVector.getFlag(0); }
+ void setIsValid(bool Value) { ParamMovesVector.setFlag(0, !Value); }
SourceLocation Loc;
- SmallVector<Stmt *, 4> ParamMovesVector;
- const bool IsPromiseDependentType;
+ llvm::SmallVectorWithFlags<Stmt *, 4, 2> ParamMovesVector;
+ bool getIsPromiseDependentType() const { return ParamMovesVector.getFlag(1); }
CXXRecordDecl *PromiseRecordDecl = nullptr;
public:
@@ -50,7 +52,7 @@ class CoroutineStmtBuilder : public CoroutineBodyStmt::CtorArgs {
/// name lookup.
bool buildDependentStatements();
- bool isInvalid() const { return !this->IsValid; }
+ bool isInvalid() const { return !this->getIsValid(); }
private:
bool makePromiseStmt();
diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp
index bbe6f644609bf..bc159668ea2ab 100644
--- a/clang/lib/Sema/JumpDiagnostics.cpp
+++ b/clang/lib/Sema/JumpDiagnostics.cpp
@@ -22,6 +22,7 @@
#include "clang/Sema/SemaAMDGPU.h"
#include "clang/Sema/SemaInternal.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
using namespace clang;
namespace {
@@ -41,7 +42,7 @@ class JumpScopeChecker {
/// Permissive - True when recovering from errors, in which case precautions
/// are taken to handle incomplete scope information.
- const bool Permissive;
+ bool getPermissive() const { return MustTailStmts.getFlag(0); }
/// GotoScope - This is a record that we use to keep track of all of the
/// scopes that are introduced by VLAs and other things that scope jumps like
@@ -75,7 +76,7 @@ class JumpScopeChecker {
SmallVector<Stmt*, 4> IndirectJumps;
SmallVector<LabelDecl *, 4> IndirectJumpTargets;
- SmallVector<AttributedStmt *, 4> MustTailStmts;
+ llvm::SmallVectorWithFlags<AttributedStmt *, 4> MustTailStmts;
public:
JumpScopeChecker(Stmt *Body, Sema &S);
@@ -102,10 +103,12 @@ class JumpScopeChecker {
};
} // end anonymous namespace
-#define CHECK_PERMISSIVE(x) (assert(Permissive || !(x)), (Permissive && (x)))
+#define CHECK_PERMISSIVE(x) \
+ (assert(getPermissive() || !(x)), (getPermissive() && (x)))
JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s)
- : S(s), Permissive(s.hasAnyUnrecoverableErrorsInThisFunction()) {
+ : S(s), MustTailStmts(decltype(this->MustTailStmts)::withFlags(
+ unsigned(bool(s.hasAnyUnrecoverableErrorsInThisFunction())))) {
// Add a scope entry for function scope.
Scopes.push_back(GotoScope(~0U, ~0U, ~0U, SourceLocation()));
diff --git a/clang/lib/Sema/ScopeInfo.cpp b/clang/lib/Sema/ScopeInfo.cpp
index d089836fa36dd..b8182c06aaa67 100644
--- a/clang/lib/Sema/ScopeInfo.cpp
+++ b/clang/lib/Sema/ScopeInfo.cpp
@@ -253,7 +253,7 @@ bool LambdaScopeInfo::lambdaCaptureShouldBeConst() const {
return ExplicitObjectParameter->getType()
.getNonReferenceType()
.isConstQualified();
- return !Mutable;
+ return !getMutable();
}
FunctionScopeInfo::~FunctionScopeInfo() { }
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index bae41a6e6f5cf..5a94bb96bf8fa 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -113,10 +113,10 @@ DarwinSDKInfo *
Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc,
StringRef Platform) {
auto *SDKInfo = getDarwinSDKInfoForAvailabilityChecking();
- if (!SDKInfo && !WarnedDarwinSDKInfoMissing) {
+ if (!SDKInfo && !getWarnedDarwinSDKInfoMissing()) {
Diag(Loc, diag::warn_missing_sdksettings_for_availability_checking)
<< Platform;
- WarnedDarwinSDKInfoMissing = true;
+ setWarnedDarwinSDKInfoMissing(true);
}
return SDKInfo;
}
@@ -314,7 +314,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
X86Ptr(std::make_unique<SemaX86>(*this)),
MSPointerToMemberRepresentationMethod(
LangOpts.getMSPointerToMemberRepresentationMethod()),
- MSStructPragmaOn(false), VtorDispStack(LangOpts.getVtorDispMode()),
+ VtorDispStack(LangOpts.getVtorDispMode()),
AlignPackStack(AlignPackInfo(getLangOpts().XLPragmaPack)),
DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
CodeSegStack(nullptr), StrictGuardStackCheckStack(false),
@@ -326,14 +326,13 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
FullyCheckedComparisonCategories(
static_cast<unsigned>(ComparisonCategoryType::Last) + 1),
StdSourceLocationImplDecl(nullptr), CXXTypeInfoDecl(nullptr),
- GlobalNewDeleteDeclared(false), DisableTypoCorrection(false),
- TyposCorrected(0), IsBuildingRecoveryCallExpr(false),
- CurrentInstantiationScope(nullptr), NonInstantiationEntries(0),
- ArgPackSubstIndex(std::nullopt), SatisfactionCache(Context) {
+ TyposCorrected(0), CurrentInstantiationScope(nullptr),
+ NonInstantiationEntries(0), ArgPackSubstIndex(std::nullopt),
+ SatisfactionCache(Context) {
assert(pp.TUKind == TUKind);
TUScope = nullptr;
- LoadedExternalKnownNamespaces = false;
+ setLoadedExternalKnownNamespaces(false);
for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I)
ObjC().NSNumberLiteralMethods[I] = nullptr;
@@ -1438,9 +1437,9 @@ void Sema::ActOnEndOfTranslationUnit() {
return false;
};
- CurrentModule->NamedModuleHasInit =
+ CurrentModule->setNamedModuleHasInit(
DoesModNeedInit(CurrentModule) ||
- llvm::any_of(CurrentModule->submodules(), DoesModNeedInit);
+ llvm::any_of(CurrentModule->submodules(), DoesModNeedInit));
}
if (TUKind == TU_ClangModule) {
@@ -2711,7 +2710,7 @@ CapturingScopeInfo *Sema::getEnclosingLambdaOrBlock() const {
if (auto *CSI = dyn_cast<CapturingScopeInfo>(Scope)) {
auto *LSI = dyn_cast<LambdaScopeInfo>(CSI);
if (LSI && LSI->Lambda && !LSI->Lambda->Encloses(CurContext) &&
- LSI->AfterParameterList) {
+ LSI->getAfterParameterList()) {
// We have switched contexts due to template instantiation.
// FIXME: We should swap out the FunctionScopes during code synthesis
// so that we don't need to check for this.
@@ -2738,7 +2737,8 @@ LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
}
auto *CurLSI = dyn_cast<LambdaScopeInfo>(*I);
if (CurLSI && CurLSI->Lambda && CurLSI->CallOperator &&
- !CurLSI->Lambda->Encloses(CurContext) && CurLSI->AfterParameterList) {
+ !CurLSI->Lambda->Encloses(CurContext) &&
+ CurLSI->getAfterParameterList()) {
// We have switched contexts due to template instantiation.
assert(!CodeSynthesisContexts.empty());
return nullptr;
@@ -2805,12 +2805,12 @@ bool Sema::areDocumentationDiagsEnabled(SourceLocation Loc) {
{
// Answer as if Loc were not in a system header.
ForceSystemWarningsRAII ShowSystemWarnings(Diags);
- DocDiagsEnabledIgnoringSystem = computeDocumentationDiagsAt(Loc);
+ setDocDiagsEnabledIgnoringSystem(computeDocumentationDiagsAt(Loc));
}
DocDiagsExactComputed = 0;
}
- if (!DocDiagsEnabledIgnoringSystem)
+ if (!getDocDiagsEnabledIgnoringSystem())
return false;
DiagStateSystemClass SysClass = Diags.getDiagStateSystemClassForLoc(Loc);
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index cc2af8feb3794..c5d3de5895265 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -24,6 +24,7 @@
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
using namespace clang;
using namespace sema;
@@ -77,11 +78,11 @@ static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
namespace {
struct EffectiveContext {
- EffectiveContext() : Inner(nullptr), Dependent(false) {}
+ EffectiveContext() : Inner(nullptr) {}
explicit EffectiveContext(DeclContext *DC)
- : Inner(DC),
- Dependent(DC->isDependentContext()) {
+ : Inner(DC), Records(decltype(this->Records)::withFlags(
+ unsigned(bool(DC->isDependentContext())))) {
// An implicit deduction guide is semantically in the context enclosing the
// class template, but for access purposes behaves like the constructor
@@ -135,7 +136,7 @@ struct EffectiveContext {
}
}
- bool isDependent() const { return Dependent; }
+ bool isDependent() const { return getDependent(); }
bool includesClass(const CXXRecordDecl *R) const {
R = R->getCanonicalDecl();
@@ -152,8 +153,9 @@ struct EffectiveContext {
DeclContext *Inner;
SmallVector<FunctionDecl*, 4> Functions;
- SmallVector<CXXRecordDecl*, 4> Records;
- bool Dependent;
+ llvm::SmallVectorWithFlags<CXXRecordDecl *, 4> Records;
+ bool getDependent() const { return Records.getFlag(0); }
+ void setDependent(bool Value) { Records.setFlag(0, Value); }
};
/// Like sema::AccessedEntity, but kindly lets us scribble all over
@@ -1168,20 +1170,25 @@ struct ProtectedFriendContext {
const EffectiveContext &EC;
TemplateSpecCandidateSet *FailedTSC;
const CXXRecordDecl *NamingClass;
- bool CheckDependent;
- bool EverDependent;
+ bool getCheckDependent() const { return CurPath.getFlag(0); }
+ void setCheckDependent(bool Value) { CurPath.setFlag(0, Value); }
+ bool getEverDependent() const { return CurPath.getFlag(1); }
+ bool setEverDependent(bool Value) {
+ CurPath.setFlag(1, Value);
+ return Value;
+ }
/// The path down to the current base class.
- SmallVector<const CXXRecordDecl*, 20> CurPath;
+ llvm::SmallVectorWithFlags<const CXXRecordDecl *, 20, 2> CurPath;
ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
const CXXRecordDecl *InstanceContext,
const CXXRecordDecl *NamingClass,
TemplateSpecCandidateSet *FailedTSC)
: S(S), EC(EC), FailedTSC(FailedTSC), NamingClass(NamingClass),
- CheckDependent(InstanceContext->isDependentContext() ||
- NamingClass->isDependentContext()),
- EverDependent(false) {}
+ CurPath(decltype(this->CurPath)::withFlags(
+ unsigned(bool(InstanceContext->isDependentContext() ||
+ NamingClass->isDependentContext())))) {}
/// Check classes in the current path for friendship, starting at
/// the given index.
@@ -1191,7 +1198,9 @@ struct ProtectedFriendContext {
switch (GetFriendKind(S, EC, CurPath[I], FailedTSC)) {
case AR_accessible: return true;
case AR_inaccessible: continue;
- case AR_dependent: EverDependent = true; continue;
+ case AR_dependent:
+ setEverDependent(true);
+ continue;
}
}
return false;
@@ -1209,8 +1218,8 @@ struct ProtectedFriendContext {
if (Cur == NamingClass)
return checkFriendshipAlongPath(PrivateDepth);
- if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
- EverDependent = true;
+ if (getCheckDependent() && MightInstantiateTo(Cur, NamingClass))
+ setEverDependent(true);
// Recurse into the base classes.
for (const auto &I : Cur->bases()) {
@@ -1227,7 +1236,7 @@ struct ProtectedFriendContext {
RD = Rec;
} else {
assert(T->isDependentType() && "non-dependent base wasn't a record?");
- EverDependent = true;
+ setEverDependent(true);
continue;
}
@@ -1290,7 +1299,8 @@ static AccessResult GetProtectedFriendKind(
ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass, FailedTSC);
if (PRC.findFriendship(InstanceContext)) return AR_accessible;
- if (PRC.EverDependent) return AR_dependent;
+ if (PRC.getEverDependent())
+ return AR_dependent;
return AR_inaccessible;
}
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 35d14a4444595..4e15fcce1478b 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -88,7 +88,7 @@ void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
}
void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
- if (MSStructPragmaOn)
+ if (getMSStructPragmaOn())
RD->addAttr(MSStructAttr::CreateImplicit(Context));
// FIXME: We should merge AddAlignmentAttributesForRecord with
@@ -657,7 +657,7 @@ void Sema::DiagnoseUnterminatedPragmaAlignPack() {
}
void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
- MSStructPragmaOn = (Kind == PMSST_ON);
+ setMSStructPragmaOn((Kind == PMSST_ON));
}
void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc,
@@ -1212,7 +1212,7 @@ void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc,
if (PragmaAttributeStack[Index].Namespace == Namespace) {
for (const PragmaAttributeEntry &Entry :
PragmaAttributeStack[Index].Entries) {
- if (!Entry.IsUsed) {
+ if (!Entry.getIsUsed()) {
assert(Entry.Attribute && "Expected an attribute");
Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
<< *Entry.Attribute;
@@ -1256,7 +1256,7 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
}
if (!Applies)
continue;
- Entry.IsUsed = true;
+ Entry.setIsUsed(true);
PragmaAttributeCurrentTargetDecl = D;
ParsedAttributesView Attrs;
Attrs.addAtEnd(Attribute);
@@ -1302,7 +1302,7 @@ void Sema::ActOnPragmaMSOptimize(SourceLocation Loc, bool IsOn) {
return;
}
- MSPragmaOptimizeIsOn = IsOn;
+ setMSPragmaOptimizeIsOn(IsOn);
}
void Sema::ActOnPragmaMSFunction(
@@ -1341,7 +1341,7 @@ void Sema::AddSectionMSAllocText(FunctionDecl *FD) {
void Sema::ModifyFnAttributesMSPragmaOptimize(FunctionDecl *FD) {
// Don't modify the function attributes if it's "on". "on" resets the
// optimizations to the ones listed on the command line
- if (!MSPragmaOptimizeIsOn)
+ if (!getMSPragmaOptimizeIsOn())
AddOptnoneAttributeIfNoConflicts(FD, FD->getBeginLoc());
}
diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index 40f26dc53315a..feeb5815f9f1f 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -553,7 +553,7 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
case AR_Deprecated:
if (ObjCPropertyAccess)
diag = diag::warn_property_method_deprecated;
- else if (S.currentEvaluationContext().IsCaseExpr)
+ else if (S.currentEvaluationContext().getIsCaseExpr())
diag = diag::warn_deprecated_switch_case;
else
diag = diag::warn_deprecated;
diff --git a/clang/lib/Sema/SemaBase.cpp b/clang/lib/Sema/SemaBase.cpp
index e16ec2883b89c..c7771aef1a42a 100644
--- a/clang/lib/Sema/SemaBase.cpp
+++ b/clang/lib/Sema/SemaBase.cpp
@@ -64,7 +64,7 @@ Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc,
getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID);
bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag &&
DiagnosticIDs::isDeferrable(DiagID) &&
- (SemaRef.DeferDiags || !IsError);
+ (SemaRef.getDeferDiags() || !IsError);
// Even without -fgpu-defer-diag, defer device-side errors inside an
// implicit-H+D explicit instantiation so end-of-TU classification can
// choose between surfacing them or emitting a trap body.
@@ -75,7 +75,7 @@ Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc,
ShouldDefer = true;
auto SetIsLastErrorImmediate = [&](bool Flag) {
if (IsError)
- SemaRef.IsLastErrorImmediate = Flag;
+ SemaRef.setIsLastErrorImmediate(Flag);
};
if (!ShouldDefer) {
SetIsLastErrorImmediate(true);
diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp
index 090030ea82503..ff6dd7a5813db 100644
--- a/clang/lib/Sema/SemaCUDA.cpp
+++ b/clang/lib/Sema/SemaCUDA.cpp
@@ -968,7 +968,7 @@ SemaBase::SemaDiagnosticBuilder SemaCUDA::DiagIfDeviceCode(SourceLocation Loc,
// mode until the function is known-emitted.
if (!getLangOpts().CUDAIsDevice)
return SemaDiagnosticBuilder::K_Nop;
- if (SemaRef.IsLastErrorImmediate &&
+ if (SemaRef.getIsLastErrorImmediate() &&
getDiagnostics().getDiagnosticIDs()->isNote(DiagID))
return SemaDiagnosticBuilder::K_Immediate;
if (isImplicitHDExplicitInstantiation(CurFunContext))
@@ -1001,7 +1001,7 @@ Sema::SemaDiagnosticBuilder SemaCUDA::DiagIfHostCode(SourceLocation Loc,
// mode until the function is known-emitted.
if (getLangOpts().CUDAIsDevice)
return SemaDiagnosticBuilder::K_Nop;
- if (SemaRef.IsLastErrorImmediate &&
+ if (SemaRef.getIsLastErrorImmediate() &&
getDiagnostics().getDiagnosticIDs()->isNote(DiagID))
return SemaDiagnosticBuilder::K_Immediate;
return (SemaRef.getEmissionStatus(CurFunContext) ==
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 51506c62d4e35..6eedc84ba29b8 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -88,6 +88,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
@@ -114,6 +115,7 @@
#include <cstdint>
#include <functional>
#include <limits>
+#include <memory>
#include <optional>
#include <string>
#include <tuple>
@@ -13112,8 +13114,14 @@ static void AnalyzeAssignment(Sema &S, BinaryOperator *E) {
// Set context flag for overflow behavior type assignment analysis, use RAII
// pattern to handle nested assignments.
- llvm::SaveAndRestore OBTAssignmentContext(
- S.InOverflowBehaviorAssignmentContext, true);
+ auto OBTAssignmentContext = [PackedFlagOwner_ = std::addressof(S)] {
+ const bool PackedFlagOld_ =
+ PackedFlagOwner_->getInOverflowBehaviorAssignmentContext();
+ PackedFlagOwner_->setInOverflowBehaviorAssignmentContext(true);
+ return llvm::scope_exit([PackedFlagOwner_, PackedFlagOld_] {
+ PackedFlagOwner_->setInOverflowBehaviorAssignmentContext(PackedFlagOld_);
+ });
+ }();
AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
@@ -14674,12 +14682,12 @@ bool Sema::CheckOverflowBehaviorTypeConversion(Expr *E, QualType T,
Target->isUnsignedIntegerType()) {
// For unsigned wrap to unsigned conversions, use pedantic version
unsigned DiagId =
- InOverflowBehaviorAssignmentContext
+ getInOverflowBehaviorAssignmentContext()
? diag::warn_impcast_overflow_behavior_assignment_pedantic
: diag::warn_impcast_overflow_behavior_pedantic;
DiagnoseImpCast(*this, E, T, CC, DiagId);
} else {
- unsigned DiagId = InOverflowBehaviorAssignmentContext
+ unsigned DiagId = getInOverflowBehaviorAssignmentContext()
? diag::warn_impcast_overflow_behavior_assignment
: diag::warn_impcast_overflow_behavior;
DiagnoseImpCast(*this, E, T, CC, DiagId);
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index b592e7075afc5..65edc246997d7 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -604,8 +604,8 @@ class ConstraintSatisfactionChecker {
return nullptr;
auto &Satisfaction = Checker.Satisfaction;
auto &Cached = Iter->second.Satisfaction;
- Satisfaction.ContainsErrors = Cached.ContainsErrors;
- Satisfaction.IsSatisfied = Cached.IsSatisfied;
+ Satisfaction.setContainsErrors(Cached.containsErrors());
+ Satisfaction.setIsSatisfied(Cached.isSatisfied());
Satisfaction.Details.insert(Satisfaction.Details.begin() +
PreviousDetailsSize,
Cached.Details.begin(), Cached.Details.end());
@@ -615,8 +615,8 @@ class ConstraintSatisfactionChecker {
ExprResult cache(ExprResult E) {
UnsubstitutedConstraintSatisfactionCacheResult Cache;
auto &Satisfaction = Checker.Satisfaction;
- Cache.Satisfaction.ContainsErrors = Satisfaction.ContainsErrors;
- Cache.Satisfaction.IsSatisfied = Satisfaction.IsSatisfied;
+ Cache.Satisfaction.setContainsErrors(Satisfaction.containsErrors());
+ Cache.Satisfaction.setIsSatisfied(Satisfaction.isSatisfied());
Cache.Satisfaction.Details.insert(Cache.Satisfaction.Details.end(),
Satisfaction.Details.begin() +
PreviousDetailsSize,
@@ -714,8 +714,8 @@ ExprResult ConstraintSatisfactionChecker::EvaluateAtomicConstraint(
llvm::FoldingSetNodeID ID;
if (Template &&
DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, &MLTAL)) {
- Satisfaction.IsSatisfied = false;
- Satisfaction.ContainsErrors = true;
+ Satisfaction.setIsSatisfied(false);
+ Satisfaction.setContainsErrors(true);
return ExprEmpty();
}
SatisfactionStackRAII StackRAII(S, Template, ID);
@@ -810,7 +810,7 @@ ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
if (S.SubstTemplateArgumentsInParameterMapping(
Constraint.getParameterMapping(), Constraint.getBeginLoc(), MLTAL,
SubstArgs)) {
- Satisfaction.IsSatisfied = false;
+ Satisfaction.setIsSatisfied(false);
if (Trap.hasErrorOccurred())
consumeSFINAEFailure(Info, Satisfaction);
return std::nullopt;
@@ -872,7 +872,7 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
if (!SubstitutedArgs) {
- Satisfaction.IsSatisfied = false;
+ Satisfaction.setIsSatisfied(false);
return ExprError();
}
@@ -900,8 +900,8 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
// diagnostics. SO, add a failure detail that will cause us to make this
// overload set not viable.
if (SubstitutedAtomicExpr.get()->containsErrors()) {
- Satisfaction.IsSatisfied = false;
- Satisfaction.ContainsErrors = true;
+ Satisfaction.setIsSatisfied(false);
+ Satisfaction.setContainsErrors(true);
PartialDiagnostic Msg = S.PDiag(diag::note_constraint_references_error);
Satisfaction.Details.emplace_back(
@@ -912,8 +912,8 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
}
if (SubstitutedAtomicExpr.get()->isValueDependent()) {
- Satisfaction.IsSatisfied = true;
- Satisfaction.ContainsErrors = false;
+ Satisfaction.setIsSatisfied(true);
+ Satisfaction.setContainsErrors(false);
return SubstitutedAtomicExpr;
}
@@ -935,8 +935,8 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
assert(EvalResult.Val.isInt() &&
"evaluating bool expression didn't produce int");
- Satisfaction.IsSatisfied = EvalResult.Val.getInt().getBoolValue();
- if (!Satisfaction.IsSatisfied)
+ Satisfaction.setIsSatisfied(EvalResult.Val.getInt().getBoolValue());
+ if (!Satisfaction.isSatisfied())
Satisfaction.Details.emplace_back(SubstitutedAtomicExpr.get());
return SubstitutedAtomicExpr;
@@ -971,7 +971,7 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
static_cast<const NormalizedConstraintWithParamMapping &>(Constraint),
MLTAL, SubstitutedOutermost);
if (!SubstitutedArgs) {
- Satisfaction.IsSatisfied = false;
+ Satisfaction.setIsSatisfied(false);
return ExprError();
}
@@ -988,15 +988,15 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
return ExprEmpty();
if (*NumExpansions == 0) {
- Satisfaction.IsSatisfied = Conjunction;
+ Satisfaction.setIsSatisfied(Conjunction);
return ExprEmpty();
}
ExprResult Out;
for (unsigned I = 0; I < *NumExpansions; I++) {
Sema::ArgPackSubstIndexRAII SubstIndex(S, I);
- Satisfaction.IsSatisfied = false;
- Satisfaction.ContainsErrors = false;
+ Satisfaction.setIsSatisfied(false);
+ Satisfaction.setContainsErrors(false);
ExprResult Expr =
ConstraintSatisfactionChecker(S, Template, TopLevelConceptId,
TemplateNameLoc, UnsignedOrNone(I),
@@ -1014,13 +1014,13 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
Constraint.getBeginLoc(),
FPOptionsOverride{});
}
- if (!Conjunction && Satisfaction.IsSatisfied) {
+ if (!Conjunction && Satisfaction.isSatisfied()) {
Satisfaction.Details.erase(Satisfaction.Details.begin() +
EffectiveDetailEndIndex,
Satisfaction.Details.end());
break;
}
- if (Satisfaction.IsSatisfied != Conjunction)
+ if (Satisfaction.isSatisfied() != Conjunction)
return Out;
}
@@ -1050,7 +1050,7 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
SubstitutionInTemplateArguments(Constraint, MLTAL, SubstitutedOutermost);
if (!SubstitutedArgs) {
- Satisfaction.IsSatisfied = false;
+ Satisfaction.setIsSatisfied(false);
return ExprError();
}
@@ -1076,7 +1076,7 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
} else if (S.SubstTemplateArguments(Ori->arguments(), *SubstitutedArgs,
OutArgs) ||
Trap.hasErrorOccurred()) {
- Satisfaction.IsSatisfied = false;
+ Satisfaction.setIsSatisfied(false);
if (Trap.hasErrorOccurred())
consumeSFINAEFailure(Info, Satisfaction);
return ExprError();
@@ -1140,7 +1140,7 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
// ConceptIdConstraint is only relevant for diagnostics,
// so if the normalized constraint is satisfied, we should not
// substitute into the constraint.
- if (Satisfaction.IsSatisfied)
+ if (Satisfaction.isSatisfied())
return E;
ParameterMappingInstantiationCache PMCache(
@@ -1163,26 +1163,27 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
ExprResult LHS = Evaluate(Constraint.getLHS(), MLTAL);
- if (Conjunction && (!Satisfaction.IsSatisfied || Satisfaction.ContainsErrors))
+ if (Conjunction &&
+ (!Satisfaction.isSatisfied() || Satisfaction.containsErrors()))
return LHS;
- if (!Conjunction && !LHS.isInvalid() && Satisfaction.IsSatisfied &&
- !Satisfaction.ContainsErrors)
+ if (!Conjunction && !LHS.isInvalid() && Satisfaction.isSatisfied() &&
+ !Satisfaction.containsErrors())
return LHS;
- Satisfaction.ContainsErrors = false;
- Satisfaction.IsSatisfied = false;
+ Satisfaction.setContainsErrors(false);
+ Satisfaction.setIsSatisfied(false);
ExprResult RHS = Evaluate(Constraint.getRHS(), MLTAL);
- if (!Conjunction && !RHS.isInvalid() && Satisfaction.IsSatisfied &&
- !Satisfaction.ContainsErrors)
+ if (!Conjunction && !RHS.isInvalid() && Satisfaction.isSatisfied() &&
+ !Satisfaction.containsErrors())
Satisfaction.Details.erase(Satisfaction.Details.begin() +
EffectiveDetailEndIndex,
Satisfaction.Details.end());
if (!BuildExpression)
- return Satisfaction.ContainsErrors ? ExprError() : ExprEmpty();
+ return Satisfaction.containsErrors() ? ExprError() : ExprEmpty();
if (!LHS.isUsable())
return RHS;
@@ -1229,7 +1230,7 @@ static bool CheckConstraintSatisfaction(
*ConvertedExpr = nullptr;
if (AssociatedConstraints.empty()) {
- Satisfaction.IsSatisfied = true;
+ Satisfaction.setIsSatisfied(true);
return false;
}
@@ -1240,7 +1241,7 @@ static bool CheckConstraintSatisfaction(
// attempted later and diagnosed, such as function template specializations,
// but that's not the case for concept specializations.
if (TemplateArgsLists.isAnyArgInstantiationDependent()) {
- Satisfaction.IsSatisfied = true;
+ Satisfaction.setIsSatisfied(true);
return false;
}
@@ -1267,7 +1268,7 @@ static bool CheckConstraintSatisfaction(
const NormalizedConstraint *C =
S.getNormalizedAssociatedConstraints(Template, AssociatedConstraints);
if (!C) {
- Satisfaction.IsSatisfied = false;
+ Satisfaction.setIsSatisfied(false);
return true;
}
@@ -1301,7 +1302,7 @@ bool Sema::CheckConstraintSatisfaction(
return TemplateIDRange.printToString(getSourceManager());
});
if (AssociatedConstraints.empty()) {
- OutSatisfaction.IsSatisfied = true;
+ OutSatisfaction.setIsSatisfied(true);
return false;
}
const auto *Template = dyn_cast_if_present<const NamedDecl *>(Entity);
@@ -1313,7 +1314,7 @@ bool Sema::CheckConstraintSatisfaction(
// Invalid templates could make their way here. Substituting them could result
// in dependent expressions.
if (Template->isInvalidDecl()) {
- OutSatisfaction.IsSatisfied = false;
+ OutSatisfaction.setIsSatisfied(false);
return true;
}
@@ -1504,7 +1505,7 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
if (FD->isDependentContext() ||
FD->getTemplatedKind() ==
FunctionDecl::TK_FunctionTemplateSpecialization) {
- Satisfaction.IsSatisfied = true;
+ Satisfaction.setIsSatisfied(true);
return false;
}
@@ -1701,7 +1702,7 @@ bool Sema::EnsureTemplateArgumentListConstraints(
TD->getAssociatedConstraints(AssociatedConstraints);
if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists,
TemplateIDRange, Satisfaction) ||
- !Satisfaction.IsSatisfied) {
+ !Satisfaction.isSatisfied()) {
SmallString<128> TemplateArgString;
TemplateArgString = " ";
TemplateArgString += getTemplateArgumentBindingsText(
@@ -1725,7 +1726,7 @@ static bool CheckFunctionConstraintsWithoutInstantiation(
SmallVector<AssociatedConstraint, 3> TemplateAC;
Template->getAssociatedConstraints(TemplateAC);
if (TemplateAC.empty()) {
- Satisfaction.IsSatisfied = true;
+ Satisfaction.setIsSatisfied(true);
return false;
}
@@ -1776,7 +1777,7 @@ bool Sema::CheckFunctionTemplateConstraints(
SmallVector<AssociatedConstraint, 3> TemplateAC;
Template->getAssociatedConstraints(TemplateAC);
if (TemplateAC.empty()) {
- Satisfaction.IsSatisfied = true;
+ Satisfaction.setIsSatisfied(true);
return false;
}
@@ -2056,7 +2057,7 @@ void Sema::DiagnoseUnsatisfiedConstraint(
const ConstraintSatisfaction &Satisfaction, SourceLocation Loc,
bool First) {
- assert(!Satisfaction.IsSatisfied &&
+ assert(!Satisfaction.isSatisfied() &&
"Attempted to diagnose a satisfied constraint");
::DiagnoseUnsatisfiedConstraint(*this, Satisfaction.Details, Loc, First);
}
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index d68a9ec2d8f35..48c4449605035 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -1261,38 +1261,39 @@ CoroutineStmtBuilder::CoroutineStmtBuilder(Sema &S, FunctionDecl &FD,
sema::FunctionScopeInfo &Fn,
Stmt *Body)
: S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
- IsPromiseDependentType(
- !Fn.CoroutinePromise ||
- Fn.CoroutinePromise->getType()->isDependentType()) {
+ ParamMovesVector(decltype(this->ParamMovesVector)::withFlags(
+ (unsigned(bool(!Fn.CoroutinePromise ||
+ Fn.CoroutinePromise->getType()->isDependentType()))
+ << 1))) {
this->Body = buildCoroutineBody(Body, S.getASTContext());
for (auto KV : Fn.CoroutineParameterMoves)
this->ParamMovesVector.push_back(KV.second);
this->ParamMoves = this->ParamMovesVector;
- if (!IsPromiseDependentType) {
+ if (!getIsPromiseDependentType()) {
PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
assert(PromiseRecordDecl && "Type should have already been checked");
}
- this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
+ this->setIsValid(makePromiseStmt() && makeInitialAndFinalSuspend());
}
bool CoroutineStmtBuilder::buildStatements() {
- assert(this->IsValid && "coroutine already invalid");
- this->IsValid = makeReturnObject();
- if (this->IsValid && !IsPromiseDependentType)
+ assert(this->getIsValid() && "coroutine already invalid");
+ this->setIsValid(makeReturnObject());
+ if (this->getIsValid() && !getIsPromiseDependentType())
buildDependentStatements();
- return this->IsValid;
+ return this->getIsValid();
}
bool CoroutineStmtBuilder::buildDependentStatements() {
- assert(this->IsValid && "coroutine already invalid");
- assert(!this->IsPromiseDependentType &&
+ assert(this->getIsValid() && "coroutine already invalid");
+ assert(!this->getIsPromiseDependentType() &&
"coroutine cannot have a dependent promise type");
- this->IsValid = makeOnException() && makeOnFallthrough() &&
- makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
- makeNewAndDeleteExpr();
- return this->IsValid;
+ this->setIsValid(makeOnException() && makeOnFallthrough() &&
+ makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
+ makeNewAndDeleteExpr());
+ return this->getIsValid();
}
bool CoroutineStmtBuilder::makePromiseStmt() {
@@ -1339,7 +1340,7 @@ static bool diagReturnOnAllocFailure(Sema &S, Expr *E,
}
bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
- assert(!IsPromiseDependentType &&
+ assert(!getIsPromiseDependentType() &&
"cannot make statement while the promise type is dependent");
// [dcl.fct.def.coroutine]p10
@@ -1427,7 +1428,7 @@ static bool collectPlacementArgs(Sema &S, FunctionDecl &FD, SourceLocation Loc,
bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
// Form and check allocation and deallocation calls.
- assert(!IsPromiseDependentType &&
+ assert(!getIsPromiseDependentType() &&
"cannot make statement while the promise type is dependent");
QualType PromiseType = Fn.CoroutinePromise->getType();
@@ -1756,7 +1757,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
}
bool CoroutineStmtBuilder::makeOnFallthrough() {
- assert(!IsPromiseDependentType &&
+ assert(!getIsPromiseDependentType() &&
"cannot make statement while the promise type is dependent");
// [dcl.fct.def.coroutine]/p6
@@ -1813,7 +1814,7 @@ bool CoroutineStmtBuilder::makeOnFallthrough() {
bool CoroutineStmtBuilder::makeOnException() {
// Try to form 'p.unhandled_exception();'
- assert(!IsPromiseDependentType &&
+ assert(!getIsPromiseDependentType() &&
"cannot make statement while the promise type is dependent");
const bool RequireUnhandledException = S.getLangOpts().CXXExceptions;
@@ -1878,7 +1879,7 @@ static void noteMemberDeclaredHere(Sema &S, Expr *E, FunctionScopeInfo &Fn) {
}
bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
- assert(!IsPromiseDependentType &&
+ assert(!getIsPromiseDependentType() &&
"cannot make statement while the promise type is dependent");
assert(this->ReturnValue && "ReturnValue must be already formed");
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4f6e65c1c4708..33fb334c02c5e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -71,6 +71,7 @@
#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cstring>
+#include <memory>
#include <optional>
#include <unordered_map>
@@ -14460,8 +14461,14 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// we should destroy the first Temp before constructing the second.
// Set context flag for OverflowBehaviorType initialization analysis
- llvm::SaveAndRestore OBTAssignmentContext(InOverflowBehaviorAssignmentContext,
- true);
+ auto OBTAssignmentContext = [PackedFlagOwner_ = this] {
+ const bool PackedFlagOld_ =
+ PackedFlagOwner_->getInOverflowBehaviorAssignmentContext();
+ PackedFlagOwner_->setInOverflowBehaviorAssignmentContext(true);
+ return llvm::scope_exit([PackedFlagOwner_, PackedFlagOld_] {
+ PackedFlagOwner_->setInOverflowBehaviorAssignmentContext(PackedFlagOld_);
+ });
+ }();
ExprResult Result =
ActOnFinishFullExpr(Init, VDecl->getLocation(),
/*DiscardedValue*/ false, VDecl->isConstexpr());
@@ -16454,8 +16461,8 @@ LambdaScopeInfo *Sema::RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator) {
// where we would set the CurContext to the lambda operator before
// substituting into it. In this case the flag needs to be true such that
// tryCaptureVariable can correctly handle potential captures thereof.
- LSI->AfterParameterList = CurContext == CallOperator;
- LSI->BeforeCompoundStatement = false;
+ LSI->setAfterParameterList(CurContext == CallOperator);
+ LSI->setBeforeCompoundStatement(false);
// GLTemplateParameterList is necessary for getCurGenericLambda() which is
// used at the point of dealing with potential captures.
@@ -16478,7 +16485,7 @@ LambdaScopeInfo *Sema::RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator) {
DeclarationNameInfo DNI = CallOperator->getNameInfo();
LSI->IntroducerRange = DNI.getCXXOperatorNameRange();
- LSI->Mutable = !CallOperator->isConst();
+ LSI->setMutable(!CallOperator->isConst());
if (CallOperator->isExplicitObjectMemberFunction())
LSI->ExplicitObjectParameter = CallOperator->getParamDecl(0);
@@ -17037,7 +17044,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation,
// In C++11, we don't use 'auto' deduction rules for lambda call
// operators because we don't support return type deduction.
auto *LSI = getCurLambda();
- if (LSI->HasImplicitReturnType) {
+ if (LSI->getHasImplicitReturnType()) {
deduceClosureReturnType(*LSI);
// C++11 [expr.prim.lambda]p4:
@@ -20058,7 +20065,7 @@ static void SetEligibleMethods(Sema &S, CXXRecordDecl *Record,
if (S.CheckFunctionConstraints(Method, Satisfaction))
SatisfactionStatus.push_back(false);
else
- SatisfactionStatus.push_back(Satisfaction.IsSatisfied);
+ SatisfactionStatus.push_back(Satisfaction.isSatisfied());
}
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index cd9771526bee3..b3d518b30dcc2 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -50,6 +50,7 @@
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -3821,23 +3822,24 @@ namespace {
llvm::SmallPtrSetImpl<QualType> &BaseClasses;
// Vector of decls to be removed from the Decl set prior to visiting the
// nodes. These Decls may have been initialized in the prior initializer.
- llvm::SmallVector<ValueDecl*, 4> DeclsToRemove;
+ llvm::SmallVectorWithFlags<ValueDecl *, 4> DeclsToRemove;
// If non-null, add a note to the warning pointing back to the constructor.
const CXXConstructorDecl *Constructor;
// Variables to hold state when processing an initializer list. When
// InitList is true, special case initialization of FieldDecls matching
// InitListFieldDecl.
- bool InitList;
+ bool getInitList() const { return DeclsToRemove.getFlag(0); }
+ void setInitList(bool Value) { DeclsToRemove.setFlag(0, Value); }
FieldDecl *InitListFieldDecl;
llvm::SmallVector<unsigned, 4> InitFieldIndex;
public:
typedef EvaluatedExprVisitor<UninitializedFieldVisitor> Inherited;
UninitializedFieldVisitor(Sema &S,
- llvm::SmallPtrSetImpl<ValueDecl*> &Decls,
+ llvm::SmallPtrSetImpl<ValueDecl *> &Decls,
llvm::SmallPtrSetImpl<QualType> &BaseClasses)
- : Inherited(S.Context), S(S), Decls(Decls), BaseClasses(BaseClasses),
- Constructor(nullptr), InitList(false), InitListFieldDecl(nullptr) {}
+ : Inherited(S.Context), S(S), Decls(Decls), BaseClasses(BaseClasses),
+ Constructor(nullptr), InitListFieldDecl(nullptr) {}
// Returns true if the use of ME is not an uninitialized use.
bool IsInitListMemberExprInitialized(MemberExpr *ME,
@@ -3937,7 +3939,7 @@ namespace {
const bool IsReference = FoundVD->getType()->isReferenceType();
- if (InitList && !AddressOf && FoundVD == InitListFieldDecl) {
+ if (getInitList() && !AddressOf && FoundVD == InitListFieldDecl) {
// Special checking for initializer lists.
if (IsInitListMemberExprInitialized(ME, CheckReferenceOnly)) {
return;
@@ -4031,12 +4033,12 @@ namespace {
InitListExpr *ILE = dyn_cast<InitListExpr>(E);
if (ILE && Field) {
- InitList = true;
+ setInitList(true);
InitListFieldDecl = Field;
InitFieldIndex.clear();
CheckInitListExpr(ILE);
} else {
- InitList = false;
+ setInitList(false);
Visit(E);
}
@@ -6705,7 +6707,7 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
if (BC->getTrailingRequiresClause()) {
ConstraintSatisfaction Satisfaction;
if (CheckFunctionConstraints(BC, Satisfaction) ||
- !Satisfaction.IsSatisfied)
+ !Satisfaction.isSatisfied())
continue;
}
findInheritingConstructor(Class->getLocation(), BC, S);
@@ -6776,7 +6778,7 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
// specialization.
ConstraintSatisfaction Satisfaction;
if (CheckFunctionConstraints(MD, Satisfaction) ||
- !Satisfaction.IsSatisfied)
+ !Satisfaction.isSatisfied())
continue;
}
}
@@ -8637,12 +8639,13 @@ class DefaultedComparisonAnalyzer
/// A list of statements.
struct StmtListResult {
- bool IsInvalid = false;
- llvm::SmallVector<Stmt*, 16> Stmts;
+ bool getIsInvalid() const { return Stmts.getFlag(0); }
+ void setIsInvalid(bool Value) { Stmts.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<Stmt *, 16> Stmts;
bool add(const StmtResult &S) {
- IsInvalid |= S.isInvalid();
- if (IsInvalid)
+ setIsInvalid(int(getIsInvalid()) | (S.isInvalid()));
+ if (getIsInvalid())
return true;
Stmts.push_back(S.get());
return false;
@@ -8674,7 +8677,7 @@ class DefaultedComparisonSynthesizer
Sema::CompoundScopeRAII CompoundScope(S);
StmtListResult Stmts = visit();
- if (Stmts.IsInvalid)
+ if (Stmts.getIsInvalid())
return StmtError();
ExprResult RetVal;
@@ -8691,7 +8694,7 @@ class DefaultedComparisonSynthesizer
// Join the comparisons with '&&'s and return the result. Use a right
// fold (traversing the conditions right-to-left), because that
// short-circuits more naturally.
- auto OldStmts = std::move(Stmts.Stmts);
+ auto OldStmts = llvm::SmallVector<Stmt *, 16>(std::move(Stmts.Stmts));
Stmts.Stmts.clear();
ExprResult CmpSoFar;
// Finish a particular comparison chain.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e29caaab8e3f3..0f111ca79359f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -64,6 +64,7 @@
#include "clang/Sema/SemaPseudoObject.h"
#include "clang/Sema/Template.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/ConvertUTF.h"
@@ -71,6 +72,7 @@
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/TypeSize.h"
#include <limits>
+#include <memory>
#include <optional>
using namespace clang;
@@ -301,7 +303,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
// A diagnostic will have already been generated (non-constant
// constraint expression, for example)
return true;
- if (!Satisfaction.IsSatisfied) {
+ if (!Satisfaction.isSatisfied()) {
Diag(Loc,
diag::err_reference_to_function_with_unsatisfied_constraints)
<< D;
@@ -2130,7 +2132,7 @@ static Decl *getPredefinedExprDecl(Sema &S, DeclContext *DC) {
while (LSI != E && !isa<LambdaScopeInfo>(*LSI))
++LSI;
assert(LSI != E && "Should be in a lambda scope info");
- if (dyn_cast<LambdaScopeInfo>(*LSI)->BeforeCompoundStatement)
+ if (dyn_cast<LambdaScopeInfo>(*LSI)->getBeforeCompoundStatement())
DC = DC->getParent();
++LSI;
}
@@ -4903,7 +4905,7 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
// Adds overload of TransformToPotentiallyEvaluated for TypeSourceInfo to
// properly deal with VLAs in nested calls of sizeof and typeof.
if (currentEvaluationContext().isUnevaluated() &&
- currentEvaluationContext().InConditionallyConstantEvaluateContext &&
+ currentEvaluationContext().getInConditionallyConstantEvaluateContext() &&
(ExprKind == UETT_SizeOf || ExprKind == UETT_CountOf) &&
TInfo->getType()->isVariablyModifiedType())
TInfo = TransformToPotentiallyEvaluated(TInfo);
@@ -5737,8 +5739,11 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
? ExpressionEvaluationContext::ImmediateFunctionContext
: ExpressionEvaluationContext::PotentiallyEvaluated,
Param);
- ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer =
- SkipImmediateInvocations;
+ [&] {
+ auto PackedFlagValue_ = SkipImmediateInvocations;
+ return ExprEvalContexts.back()
+ .setIsCurrentlyCheckingDefaultArgumentOrInitializer(PackedFlagValue_);
+ }();
runWithSufficientStackSpace(CallLoc, [&] {
MarkDeclarationsReferencedInExpr(Init, /*SkipLocalVariables=*/true);
});
@@ -5884,8 +5889,12 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
CallLoc, Param, CurContext};
// Pass down lifetime extending flag, and collect temporaries in
// CreateMaterializeTemporaryExpr when we rewrite the call argument.
- currentEvaluationContext().InLifetimeExtendingContext =
- parentEvaluationContext().InLifetimeExtendingContext;
+ [&] {
+ auto PackedFlagValue_ =
+ parentEvaluationContext().getInLifetimeExtendingContext();
+ return currentEvaluationContext().setInLifetimeExtendingContext(
+ PackedFlagValue_);
+ }();
EnsureImmediateInvocationInDefaultArgs Immediate(*this);
ExprResult Res;
runWithSufficientStackSpace(CallLoc, [&] {
@@ -5998,12 +6007,19 @@ ExprResult Sema::BuildCXXDefaultInitInternal(SourceLocation Loc,
(V.HasImmediateCalls || (NeedRebuild && ContainsAnyTemporaries))) {
ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field,
CurContext};
- ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer =
- NestedDefaultChecking;
+ [&] {
+ auto PackedFlagValue_ = NestedDefaultChecking;
+ return ExprEvalContexts.back()
+ .setIsCurrentlyCheckingDefaultArgumentOrInitializer(PackedFlagValue_);
+ }();
// Pass down lifetime extending flag, and collect temporaries in
// CreateMaterializeTemporaryExpr when we rewrite the initializer.
- currentEvaluationContext().InLifetimeExtendingContext =
- parentEvaluationContext().InLifetimeExtendingContext;
+ [&] {
+ auto PackedFlagValue_ =
+ parentEvaluationContext().getInLifetimeExtendingContext();
+ return currentEvaluationContext().setInLifetimeExtendingContext(
+ PackedFlagValue_);
+ }();
EnsureImmediateInvocationInDefaultArgs Immediate(*this);
ExprResult Res;
@@ -17188,7 +17204,7 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {
else
CurContext = Block;
- getCurBlock()->HasImplicitReturnType = true;
+ getCurBlock()->setHasImplicitReturnType(true);
// Enter a new evaluation context to insulate the block from any
// cleanups from the enclosing full-expression.
@@ -17252,7 +17268,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
if (RetTy != Context.DependentTy) {
CurBlock->ReturnType = RetTy;
CurBlock->TheDecl->setBlockMissingReturnType(false);
- CurBlock->HasImplicitReturnType = false;
+ CurBlock->setHasImplicitReturnType(false);
}
// Push block parameters from the declarator if we had them.
@@ -17333,7 +17349,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
maybeAddDeclWithEffects(BD);
- if (BSI->HasImplicitReturnType)
+ if (BSI->getHasImplicitReturnType())
deduceClosureReturnType(*BSI);
QualType RetTy = Context.VoidTy;
@@ -17479,7 +17495,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
PoppedFunctionScopePtr ScopeRAII = PopFunctionScopeInfo(&WP, BD, BlockTy);
BlockExpr *Result = new (Context)
- BlockExpr(BD, BlockTy, BSI->ContainsUnexpandedParameterPack);
+ BlockExpr(BD, BlockTy, BSI->getContainsUnexpandedParameterPack());
// If the block isn't obviously global, i.e. it captures anything at
// all, then we need to do a few things in the surrounding context:
@@ -18490,19 +18506,29 @@ Sema::PushExpressionEvaluationContext(
// Discarded statements and immediate contexts nested in other
// discarded statements or immediate context are themselves
// a discarded statement or an immediate context, respectively.
- ExprEvalContexts.back().InDiscardedStatement =
- parentEvaluationContext().isDiscardedStatementContext();
+ [&] {
+ auto PackedFlagValue_ =
+ parentEvaluationContext().isDiscardedStatementContext();
+ return ExprEvalContexts.back().setInDiscardedStatement(PackedFlagValue_);
+ }();
// C++23 [expr.const]/p15
// An expression or conversion is in an immediate function context if [...]
// it is a subexpression of a manifestly constant-evaluated expression or
// conversion.
const auto &Prev = parentEvaluationContext();
- ExprEvalContexts.back().InImmediateFunctionContext =
- Prev.isImmediateFunctionContext() || Prev.isConstantEvaluated();
+ [&] {
+ auto PackedFlagValue_ =
+ Prev.isImmediateFunctionContext() || Prev.isConstantEvaluated();
+ return ExprEvalContexts.back().setInImmediateFunctionContext(
+ PackedFlagValue_);
+ }();
- ExprEvalContexts.back().InImmediateEscalatingFunctionContext =
- Prev.InImmediateEscalatingFunctionContext;
+ [&] {
+ auto PackedFlagValue_ = Prev.getInImmediateEscalatingFunctionContext();
+ return ExprEvalContexts.back().setInImmediateEscalatingFunctionContext(
+ PackedFlagValue_);
+ }();
Cleanup.reset();
if (!MaybeODRUseExprs.empty())
@@ -18531,7 +18557,7 @@ void Sema::PushExpressionEvaluationContextForFunction(
parentEvaluationContext();
Sema::ExpressionEvaluationContextRecord &Current = currentEvaluationContext();
- Current.InDiscardedStatement = false;
+ Current.setInDiscardedStatement(false);
if (FD) {
@@ -18543,16 +18569,16 @@ void Sema::PushExpressionEvaluationContextForFunction(
// function is entered, we need to reset this tracking, since the entered
// function might be not an immediate function.
- Current.InImmediateEscalatingFunctionContext =
- getLangOpts().CPlusPlus20 && FD->isImmediateEscalating();
+ Current.setInImmediateEscalatingFunctionContext(
+ getLangOpts().CPlusPlus20 && FD->isImmediateEscalating());
if (isLambdaMethod(FD))
- Current.InImmediateFunctionContext =
+ Current.setInImmediateFunctionContext(
FD->isConsteval() ||
(isLambdaMethod(FD) && (Parent.isConstantEvaluated() ||
- Parent.isImmediateFunctionContext()));
+ Parent.isImmediateFunctionContext())));
else
- Current.InImmediateFunctionContext = FD->isConsteval();
+ Current.setInImmediateFunctionContext(FD->isConsteval());
}
}
@@ -18628,7 +18654,7 @@ void Sema::CheckUnusedVolatileAssignment(Expr *E) {
void Sema::MarkExpressionAsImmediateEscalating(Expr *E) {
assert(getLangOpts().CPlusPlus20 &&
- ExprEvalContexts.back().InImmediateEscalatingFunctionContext &&
+ ExprEvalContexts.back().getInImmediateEscalatingFunctionContext() &&
"Cannot mark an immediate escalating expression outside of an "
"immediate escalating context");
if (auto *Call = dyn_cast<CallExpr>(E->IgnoreImplicit());
@@ -18651,7 +18677,7 @@ ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
if (isUnevaluatedContext() || !E.isUsable() || !Decl ||
!Decl->isImmediateFunction() || isAlwaysConstantEvaluatedContext() ||
isCheckingDefaultArgumentOrInitializer() ||
- RebuildingImmediateInvocation || isImmediateFunctionContext())
+ getRebuildingImmediateInvocation() || isImmediateFunctionContext())
return E;
/// Opportunistically remove the callee from ReferencesToConsteval if we can.
@@ -18681,7 +18707,7 @@ ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
};
if (!E.get()->isValueDependent() &&
- ExprEvalContexts.back().InImmediateEscalatingFunctionContext &&
+ ExprEvalContexts.back().getInImmediateEscalatingFunctionContext() &&
!CheckConstantExpressionAndKeepResult()) {
MarkExpressionAsImmediateEscalating(E.get());
return E;
@@ -18880,7 +18906,8 @@ HandleImmediateInvocations(Sema &SemaRef,
Sema::ExpressionEvaluationContextRecord &Rec) {
if ((Rec.ImmediateInvocationCandidates.size() == 0 &&
Rec.ReferenceToConsteval.size() == 0) ||
- Rec.isImmediateFunctionContext() || SemaRef.RebuildingImmediateInvocation)
+ Rec.isImmediateFunctionContext() ||
+ SemaRef.getRebuildingImmediateInvocation())
return;
// An expression or conversion is 'manifestly constant-evaluated' if it is:
@@ -18912,8 +18939,14 @@ HandleImmediateInvocations(Sema &SemaRef,
/// Prevent sema calls during the tree transform from adding pointers that
/// are already in the sets.
- llvm::SaveAndRestore DisableIITracking(
- SemaRef.RebuildingImmediateInvocation, true);
+ auto DisableIITracking = [PackedFlagOwner_ = std::addressof(SemaRef)] {
+ const bool PackedFlagOld_ =
+ PackedFlagOwner_->getRebuildingImmediateInvocation();
+ PackedFlagOwner_->setRebuildingImmediateInvocation(true);
+ return llvm::scope_exit([PackedFlagOwner_, PackedFlagOld_] {
+ PackedFlagOwner_->setRebuildingImmediateInvocation(PackedFlagOld_);
+ });
+ }();
/// Prevent diagnostic during tree transfrom as they are duplicates
Sema::TentativeAnalysisScope DisableDiag(SemaRef);
@@ -18962,9 +18995,9 @@ HandleImmediateInvocations(Sema &SemaRef,
Rec.Context ==
Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed;
if (SemaRef.inTemplateInstantiation() && IsPotentiallyEvaluated)
- ImmediateEscalating = Rec.InImmediateEscalatingFunctionContext;
+ ImmediateEscalating = Rec.getInImmediateEscalatingFunctionContext();
- if (!Rec.InImmediateEscalatingFunctionContext ||
+ if (!Rec.getInImmediateEscalatingFunctionContext() ||
(SemaRef.inTemplateInstantiation() && !ImmediateEscalating)) {
SemaRef.Diag(DR->getBeginLoc(), diag::err_invalid_consteval_take_address)
<< ND << isa<CXXRecordDecl>(ND) << FD->isConsteval();
@@ -19019,8 +19052,8 @@ void Sema::PopExpressionEvaluationContext() {
// Append the collected materialized temporaries into previous context before
// exit if the previous also is a lifetime extending context.
- if (getLangOpts().CPlusPlus23 && Rec.InLifetimeExtendingContext &&
- parentEvaluationContext().InLifetimeExtendingContext &&
+ if (getLangOpts().CPlusPlus23 && Rec.getInLifetimeExtendingContext() &&
+ parentEvaluationContext().getInLifetimeExtendingContext() &&
!Rec.ForRangeLifetimeExtendTemps.empty()) {
parentEvaluationContext().ForRangeLifetimeExtendTemps.append(
Rec.ForRangeLifetimeExtendTemps);
@@ -20188,7 +20221,7 @@ bool Sema::tryCaptureVariable(
// NOT the lambda but its parent. So move away the current LSI before
// aligning DC and FunctionScopeIndexToStopAt.
if (auto *LSI = dyn_cast<LambdaScopeInfo>(FunctionScopes[FSIndex]);
- FSIndex && LSI && !LSI->AfterParameterList)
+ FSIndex && LSI && !LSI->getAfterParameterList())
--FSIndex;
assert(MaxFunctionScopesIndex <= FSIndex &&
"FunctionScopeIndexToStopAt should be no greater than FSIndex into "
@@ -20231,9 +20264,9 @@ bool Sema::tryCaptureVariable(
FunctionScopes[FunctionScopesIndex]);
bool IsInScopeDeclarationContext =
- !LSI || LSI->AfterParameterList || CurContext == LSI->CallOperator;
+ !LSI || LSI->getAfterParameterList() || CurContext == LSI->CallOperator;
- if (LSI && !LSI->AfterParameterList) {
+ if (LSI && !LSI->getAfterParameterList()) {
// This allows capturing parameters from a default value which does not
// seems correct
if (isa<ParmVarDecl>(Var) && !Var->getDeclContext()->isFunctionOrMethod())
@@ -21170,7 +21203,7 @@ static void FixDependencyOfIdExpressionsInLambdaWithDependentObjectParameter(
continue;
if (LSI->Lambda && !LSI->Lambda->Encloses(SemaRef.CurContext) &&
- LSI->AfterParameterList)
+ LSI->getAfterParameterList())
return false;
const auto *MD = LSI->CallOperator;
@@ -21263,7 +21296,7 @@ void Sema::MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base) {
if (!isUnevaluatedContext() && !isConstantEvaluatedContext() &&
!isImmediateFunctionContext() &&
!isCheckingDefaultArgumentOrInitializer() &&
- FD->isImmediateFunction() && !RebuildingImmediateInvocation &&
+ FD->isImmediateFunction() && !getRebuildingImmediateInvocation() &&
!FD->isDependentContext())
ExprEvalContexts.back().ReferenceToConsteval.insert(E);
}
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 916c5308508f1..833fc2cc282f8 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -48,6 +48,7 @@
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TypeSize.h"
@@ -1469,7 +1470,7 @@ void Sema::MarkThisReferenced(CXXThisExpr *This) {
continue;
if (LSI->Lambda && !LSI->Lambda->Encloses(CurContext) &&
- LSI->AfterParameterList)
+ LSI->getAfterParameterList())
return false;
// If this lambda captures 'this' by value, then 'this' is dependent iff
@@ -3480,7 +3481,7 @@ Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
}
void Sema::DeclareGlobalNewDelete() {
- if (GlobalNewDeleteDeclared)
+ if (getGlobalNewDeleteDeclared())
return;
// The implicitly declared new and delete operators
@@ -3572,7 +3573,7 @@ void Sema::DeclareGlobalNewDelete() {
StdAlignValT = AlignValT;
}
- GlobalNewDeleteDeclared = true;
+ setGlobalNewDeleteDeclared(true);
QualType VoidPtr = Context.getPointerType(Context.VoidTy);
QualType SizeT = Context.getSizeType();
@@ -3882,8 +3883,8 @@ class MismatchingNewDeleteDetector {
/// translation unit. False, if this is the initial analysis at the point
/// delete-expression was encountered.
explicit MismatchingNewDeleteDetector(bool EndOfTU)
- : Field(nullptr), IsArrayForm(false), EndOfTU(EndOfTU),
- HasUndefinedConstructors(false) {}
+ : Field(nullptr), NewExprs(decltype(this->NewExprs)::withFlags(
+ (unsigned(EndOfTU) << 1))) {}
/// Checks whether pointee of a delete-expression is initialized with
/// matching form of new-expression.
@@ -3903,14 +3904,16 @@ class MismatchingNewDeleteDetector {
MismatchResult analyzeField(FieldDecl *Field, bool DeleteWasArrayForm);
FieldDecl *Field;
/// List of mismatching new-expressions used for initialization of the pointee
- llvm::SmallVector<const CXXNewExpr *, 4> NewExprs;
+ llvm::SmallVectorWithFlags<const CXXNewExpr *, 4, 3> NewExprs;
/// Indicates whether delete-expression was in array form.
- bool IsArrayForm;
+ bool getIsArrayForm() const { return NewExprs.getFlag(0); }
+ void setIsArrayForm(bool Value) { NewExprs.setFlag(0, Value); }
private:
- const bool EndOfTU;
+ bool getEndOfTU() const { return NewExprs.getFlag(1); }
/// Indicates that there is at least one constructor without body.
- bool HasUndefinedConstructors;
+ bool getHasUndefinedConstructors() const { return NewExprs.getFlag(2); }
+ void setHasUndefinedConstructors(bool Value) { NewExprs.setFlag(2, Value); }
/// Returns \c CXXNewExpr from given initialization expression.
/// \param E Expression used for initializing pointee in delete-expression.
/// E can be a single-element \c InitListExpr consisting of new-expression.
@@ -3946,6 +3949,14 @@ class MismatchingNewDeleteDetector {
/// Checks whether member is initialized with mismatching form of \c new by
/// in-class initializer.
MismatchResult analyzeInClassInitializer();
+
+public:
+ MismatchingNewDeleteDetector(const MismatchingNewDeleteDetector &) = default;
+ MismatchingNewDeleteDetector(MismatchingNewDeleteDetector &&) = default;
+ MismatchingNewDeleteDetector &
+ operator=(const MismatchingNewDeleteDetector &) = delete;
+ MismatchingNewDeleteDetector &
+ operator=(MismatchingNewDeleteDetector &&) = delete;
};
}
@@ -3953,7 +3964,7 @@ MismatchingNewDeleteDetector::MismatchResult
MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) {
NewExprs.clear();
assert(DE && "Expected delete-expression");
- IsArrayForm = DE->isArrayForm();
+ setIsArrayForm(DE->isArrayForm());
const Expr *E = DE->getArgument()->IgnoreParenImpCasts();
if (const MemberExpr *ME = dyn_cast<const MemberExpr>(E)) {
return analyzeMemberExpr(ME);
@@ -3981,7 +3992,7 @@ bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit(
const CXXNewExpr *NE = nullptr;
if (Field == CI->getMember() &&
(NE = getNewExprFromInitListOrExpr(CI->getInit()))) {
- if (NE->isArray() == IsArrayForm)
+ if (NE->isArray() == getIsArrayForm())
return true;
else
NewExprs.push_back(NE);
@@ -3995,8 +4006,8 @@ bool MismatchingNewDeleteDetector::hasMatchingNewInCtor(
return false;
const FunctionDecl *Definition = CD;
if (!CD->isThisDeclarationADefinition() && !CD->isDefined(Definition)) {
- HasUndefinedConstructors = true;
- return EndOfTU;
+ setHasUndefinedConstructors(true);
+ return getEndOfTU();
}
for (const auto *CI : cast<const CXXConstructorDecl>(Definition)->inits()) {
if (hasMatchingNewInCtorInit(CI))
@@ -4010,9 +4021,9 @@ MismatchingNewDeleteDetector::analyzeInClassInitializer() {
assert(Field != nullptr && "This should be called only for members");
const Expr *InitExpr = Field->getInClassInitializer();
if (!InitExpr)
- return EndOfTU ? NoMismatch : AnalyzeLater;
+ return getEndOfTU() ? NoMismatch : AnalyzeLater;
if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) {
- if (NE->isArray() != IsArrayForm) {
+ if (NE->isArray() != getIsArrayForm()) {
NewExprs.push_back(NE);
return MemberInitMismatches;
}
@@ -4025,14 +4036,14 @@ MismatchingNewDeleteDetector::analyzeField(FieldDecl *Field,
bool DeleteWasArrayForm) {
assert(Field != nullptr && "Analysis requires a valid class member.");
this->Field = Field;
- IsArrayForm = DeleteWasArrayForm;
+ setIsArrayForm(DeleteWasArrayForm);
const CXXRecordDecl *RD = cast<const CXXRecordDecl>(Field->getParent());
for (const auto *CD : RD->ctors()) {
if (hasMatchingNewInCtor(CD))
return NoMismatch;
}
- if (HasUndefinedConstructors)
- return EndOfTU ? NoMismatch : AnalyzeLater;
+ if (getHasUndefinedConstructors())
+ return getEndOfTU() ? NoMismatch : AnalyzeLater;
if (!NewExprs.empty())
return MemberInitMismatches;
return Field->hasInClassInitializer() ? analyzeInClassInitializer()
@@ -4043,7 +4054,7 @@ MismatchingNewDeleteDetector::MismatchResult
MismatchingNewDeleteDetector::analyzeMemberExpr(const MemberExpr *ME) {
assert(ME != nullptr && "Expected a member expression");
if (FieldDecl *F = dyn_cast<FieldDecl>(ME->getMemberDecl()))
- return analyzeField(F, IsArrayForm);
+ return analyzeField(F, getIsArrayForm());
return NoMismatch;
}
@@ -4051,7 +4062,7 @@ bool MismatchingNewDeleteDetector::hasMatchingVarInit(const DeclRefExpr *D) {
const CXXNewExpr *NE = nullptr;
if (const VarDecl *VD = dyn_cast<const VarDecl>(D->getDecl())) {
if (VD->hasInit() && (NE = getNewExprFromInitListOrExpr(VD->getInit())) &&
- NE->isArray() != IsArrayForm) {
+ NE->isArray() != getIsArrayForm()) {
NewExprs.push_back(NE);
}
}
@@ -4063,7 +4074,7 @@ DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc,
const MismatchingNewDeleteDetector &Detector) {
SourceLocation EndOfDelete = SemaRef.getLocForEndOfToken(DeleteLoc);
FixItHint H;
- if (!Detector.IsArrayForm)
+ if (!Detector.getIsArrayForm())
H = FixItHint::CreateInsertion(EndOfDelete, "[]");
else {
SourceLocation RSquare = Lexer::findLocationAfterToken(
@@ -4073,11 +4084,11 @@ DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc,
H = FixItHint::CreateRemoval(SourceRange(EndOfDelete, RSquare));
}
SemaRef.Diag(DeleteLoc, diag::warn_mismatched_delete_new)
- << Detector.IsArrayForm << H;
+ << Detector.getIsArrayForm() << H;
for (const auto *NE : Detector.NewExprs)
SemaRef.Diag(NE->getExprLoc(), diag::note_allocated_here)
- << Detector.IsArrayForm;
+ << Detector.getIsArrayForm();
}
void Sema::AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE) {
@@ -7778,7 +7789,8 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
while (isa_and_nonnull<CapturedDecl>(DC))
DC = DC->getParent();
assert(
- (CurrentLSI->CallOperator == DC || !CurrentLSI->AfterParameterList) &&
+ (CurrentLSI->CallOperator == DC ||
+ !CurrentLSI->getAfterParameterList()) &&
"The current call operator must be synchronized with Sema's CurContext");
#endif // NDEBUG
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 4fe7ed151e918..1e193ddd457eb 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -37,6 +37,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -3022,10 +3023,11 @@ template <typename T> constexpr uint64_t barrierFlagValue(T Flag) {
/// the entry points.
class DiagnoseHLSLAvailability : public DynamicRecursiveASTVisitor {
Sema &SemaRef;
- bool DiagnoseAvailability;
+ bool getDiagnoseAvailability() const { return DeclsToScan.getFlag(0); }
+ void setDiagnoseAvailability(bool Value) { DeclsToScan.setFlag(0, Value); }
// Stack of functions to be scaned
- llvm::SmallVector<const FunctionDecl *, 8> DeclsToScan;
+ llvm::SmallVectorWithFlags<const FunctionDecl *, 8, 2> DeclsToScan;
// Tracks which environments functions have been scanned in.
//
@@ -3059,7 +3061,10 @@ class DiagnoseHLSLAvailability : public DynamicRecursiveASTVisitor {
// True if scanning a function that was already scanned in a different
// shader stage context. Suppress stage-independent diagnostics because
// they were reported during the first scan.
- bool ReportOnlyShaderStageIssues;
+ bool getReportOnlyShaderStageIssues() const { return DeclsToScan.getFlag(1); }
+ void setReportOnlyShaderStageIssues(bool Value) {
+ DeclsToScan.setFlag(1, Value);
+ }
// Helper methods for dealing with current stage context / environment
void SetShaderStageContext(llvm::Triple::EnvironmentType ShaderType) {
@@ -3125,9 +3130,10 @@ class DiagnoseHLSLAvailability : public DynamicRecursiveASTVisitor {
public:
DiagnoseHLSLAvailability(Sema &SemaRef, bool DiagnoseAvailability)
- : SemaRef(SemaRef), DiagnoseAvailability(DiagnoseAvailability),
+ : SemaRef(SemaRef), DeclsToScan(decltype(this->DeclsToScan)::withFlags(
+ unsigned(DiagnoseAvailability))),
CurrentShaderEnvironment(llvm::Triple::UnknownEnvironment),
- CurrentShaderStageBit(0), ReportOnlyShaderStageIssues(false) {}
+ CurrentShaderStageBit(0) {}
// AST traversal methods
void RunOnTranslationUnit(const TranslationUnitDecl *TU);
@@ -3205,7 +3211,7 @@ void DiagnoseHLSLAvailability::DiagnoseBarrierGroupSemantic(
void DiagnoseHLSLAvailability::DiagnoseBarrierScope(Expr *SemanticArg,
uint64_t MemoryFlags,
uint64_t SemanticFlags) {
- if (ReportOnlyShaderStageIssues)
+ if (getReportOnlyShaderStageIssues())
return;
const uint64_t DeviceScopeMemory =
@@ -3275,7 +3281,7 @@ void DiagnoseHLSLAvailability::HandleFunctionOrMethodRef(FunctionDecl *FD,
assert((isa<DeclRefExpr>(RefExpr) || isa<MemberExpr>(RefExpr)) &&
"expected DeclRefExpr or MemberExpr");
- if (DiagnoseAvailability)
+ if (getDiagnoseAvailability())
if (const AvailabilityAttr *AA = FindAvailabilityAttr(FD))
CheckDeclAvailability(
FD, AA, SourceRange(RefExpr->getBeginLoc(), RefExpr->getEndLoc()));
@@ -3381,7 +3387,7 @@ void DiagnoseHLSLAvailability::RunOnFunction(const FunctionDecl *FD) {
if (WasAlreadyScannedInCurrentStage(ScannedStages))
continue;
- ReportOnlyShaderStageIssues = !NeverBeenScanned(ScannedStages);
+ setReportOnlyShaderStageIssues(!NeverBeenScanned(ScannedStages));
AddToScannedFunctions(FD);
TraverseStmt(FD->getBody());
@@ -3451,7 +3457,7 @@ void DiagnoseHLSLAvailability::CheckDeclAvailability(NamedDecl *D,
// Do not report shader-stage-independent issues if scanning a function
// that was already scanned in a different shader stage context (they would
// be duplicate)
- if (ReportOnlyShaderStageIssues)
+ if (getReportOnlyShaderStageIssues())
return;
} else {
@@ -5902,13 +5908,13 @@ void SemaHLSL::deduceAddressSpace(VarDecl *Decl) {
bool IsVulkan = getASTContext().getTargetInfo().getTriple().getOS() ==
llvm::Triple::Vulkan;
if (IsVulkan && Decl->hasAttr<HLSLVkPushConstantAttr>()) {
- if (HasDeclaredAPushConstant)
+ if (getHasDeclaredAPushConstant())
SemaRef.Diag(Decl->getLocation(), diag::err_hlsl_push_constant_unique);
LangAS ImplAS = LangAS::hlsl_push_constant;
Type = SemaRef.getASTContext().getAddrSpaceQualType(Type, ImplAS);
Decl->setType(Type);
- HasDeclaredAPushConstant = true;
+ setHasDeclaredAPushConstant(true);
return;
}
@@ -6644,12 +6650,13 @@ class InitListTransformer {
// Is wrapping the destination type iterator required? This is only used for
// incomplete array types where we loop over the destination type since we
// don't know the full number of elements from the declaration.
- bool Wrap;
+ bool getWrap() const { return ArgExprs.getFlag(0); }
+ void setWrap(bool Value) { ArgExprs.setFlag(0, Value); }
bool castInitializer(Expr *E) {
assert(DstIt && "This should always be something!");
if (DstIt == DestTypes.end()) {
- if (!Wrap) {
+ if (!getWrap()) {
ArgExprs.push_back(E);
// This is odd, but it isn't technically a failure due to conversion, we
// handle mismatched counts of arguments differently.
@@ -6839,15 +6846,16 @@ class InitListTransformer {
public:
llvm::SmallVector<QualType, 16> DestTypes;
- llvm::SmallVector<Expr *, 16> ArgExprs;
+ llvm::SmallVectorWithFlags<Expr *, 16> ArgExprs;
InitListTransformer(Sema &SemaRef, const InitializedEntity &Entity)
: S(SemaRef), Ctx(SemaRef.getASTContext()),
- Wrap(Entity.getType()->isIncompleteArrayType()) {
+ ArgExprs(decltype(this->ArgExprs)::withFlags(
+ unsigned(bool(Entity.getType()->isIncompleteArrayType())))) {
InitTy = Entity.getType().getNonReferenceType();
// When we're generating initializer lists for incomplete array types we
// need to wrap around both when building the initializers and when
// generating the final initializer lists.
- if (Wrap) {
+ if (getWrap()) {
assert(InitTy->isIncompleteArrayType());
const IncompleteArrayType *IAT = Ctx.getAsIncompleteArrayType(InitTy);
InitTy = IAT->getElementType();
@@ -6862,7 +6870,7 @@ class InitListTransformer {
assert(!ArgExprs.empty() &&
"Call buildInitializerList to generate argument expressions.");
ArgIt = ArgExprs.begin();
- if (!Wrap)
+ if (!getWrap())
return generateInitListsImpl(InitTy);
llvm::SmallVector<Expr *> Inits;
while (ArgIt != ArgExprs.end())
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 0c9a92cdd0c32..2102fea757c54 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -573,13 +573,13 @@ static void buildLambdaScopeReturnType(Sema &S, LambdaScopeInfo *LSI,
CXXMethodDecl *CallOperator,
bool ExplicitResultType) {
if (ExplicitResultType) {
- LSI->HasImplicitReturnType = false;
+ LSI->setHasImplicitReturnType(false);
LSI->ReturnType = CallOperator->getReturnType();
if (!LSI->ReturnType->isDependentType() && !LSI->ReturnType->isVoidType())
S.RequireCompleteType(CallOperator->getBeginLoc(), LSI->ReturnType,
diag::err_lambda_incomplete_result);
} else {
- LSI->HasImplicitReturnType = true;
+ LSI->setHasImplicitReturnType(true);
}
}
@@ -597,8 +597,8 @@ void Sema::buildLambdaScope(LambdaScopeInfo *LSI, CXXMethodDecl *CallOperator,
LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref;
LSI->CaptureDefaultLoc = CaptureDefaultLoc;
LSI->IntroducerRange = IntroducerRange;
- LSI->ExplicitParams = ExplicitParams;
- LSI->Mutable = Mutable;
+ LSI->setExplicitParams(ExplicitParams);
+ LSI->setMutable(Mutable);
}
void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) {
@@ -751,7 +751,7 @@ static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns,
}
void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
- assert(CSI.HasImplicitReturnType);
+ assert(CSI.getHasImplicitReturnType());
// If it was ever a placeholder, it had to been deduced to DependentTy.
assert(CSI.ReturnType.isNull() || !CSI.ReturnType->isUndeducedType());
assert((!isa<LambdaScopeInfo>(CSI) || !getLangOpts().CPlusPlus14) &&
@@ -1135,7 +1135,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref;
LSI->CaptureDefaultLoc = Intro.DefaultLoc;
LSI->IntroducerRange = Intro.Range;
- LSI->AfterParameterList = false;
+ LSI->setAfterParameterList(false);
assert(LSI->NumExplicitTemplateParams == 0);
@@ -1395,7 +1395,9 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange;
}
finishLambdaExplicitCaptures(LSI);
- LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;
+ LSI->setContainsUnexpandedParameterPack(
+ LSI->getContainsUnexpandedParameterPack() |
+ (ContainsUnexpandedParameterPack));
PopDeclContext();
}
@@ -1403,7 +1405,7 @@ void Sema::ActOnLambdaClosureQualifiers(LambdaIntroducer &Intro,
SourceLocation MutableLoc) {
LambdaScopeInfo *LSI = getCurrentLambdaScopeUnsafe(*this);
- LSI->Mutable = MutableLoc.isValid();
+ LSI->setMutable(MutableLoc.isValid());
ContextRAII Context(*this, LSI->CallOperator, /*NewThisContext*/ false);
// C++11 [expr.prim.lambda]p9:
@@ -1449,10 +1451,13 @@ void Sema::ActOnLambdaClosureParameters(
AddTemplateParametersToLambdaCallOperator(LSI->CallOperator, LSI->Lambda,
TemplateParams);
LSI->Lambda->setLambdaIsGeneric(true);
- LSI->ContainsUnexpandedParameterPack |=
- TemplateParams->containsUnexpandedParameterPack();
+ [&] {
+ auto PackedFlagValue = TemplateParams->containsUnexpandedParameterPack();
+ return LSI->setContainsUnexpandedParameterPack(
+ LSI->getContainsUnexpandedParameterPack() | PackedFlagValue);
+ }();
}
- LSI->AfterParameterList = true;
+ LSI->setAfterParameterList(true);
}
void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
@@ -1461,7 +1466,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
LambdaScopeInfo *LSI = getCurrentLambdaScopeUnsafe(*this);
LSI->CallOperator->setConstexprKind(DS.getConstexprSpecifier());
- LSI->BeforeCompoundStatement = false;
+ LSI->setBeforeCompoundStatement(false);
SmallVector<ParmVarDecl *, 8> Params;
bool ExplicitResultType;
@@ -1486,7 +1491,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
if (ParamInfo.isFunctionDeclarator() != 0) {
const auto &FTI = ParamInfo.getFunctionTypeInfo();
- LSI->ExplicitParams = FTI.getLParenLoc().isValid();
+ LSI->setExplicitParams(FTI.getLParenLoc().isValid());
if (!FTIHasSingleVoidParameter(FTI)) {
Params.reserve(Params.size());
for (unsigned I = 0; I < FTI.NumParams; ++I) {
@@ -2219,10 +2224,11 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc,
CXXRecordDecl *Class = LSI->Lambda;
CXXMethodDecl *CallOperator = LSI->CallOperator;
SourceRange IntroducerRange = LSI->IntroducerRange;
- bool ExplicitParams = LSI->ExplicitParams;
- bool ExplicitResultType = !LSI->HasImplicitReturnType;
+ bool ExplicitParams = LSI->getExplicitParams();
+ bool ExplicitResultType = !LSI->getHasImplicitReturnType();
CleanupInfo LambdaCleanup = LSI->Cleanup;
- bool ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
+ bool ContainsUnexpandedParameterPack =
+ LSI->getContainsUnexpandedParameterPack();
bool IsGenericLambda = Class->isGenericLambda();
CallOperator->setLexicalDeclContext(Class);
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h
index 3db298b6fec85..eaf97298d6e19 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -21,6 +21,7 @@
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Sema.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <string>
namespace clang::lifetimes {
@@ -524,13 +525,14 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
private:
struct LifetimeBoundMacroCache {
- bool IsBuilt = false;
- SmallVector<const IdentifierInfo *> Candidates;
+ bool getIsBuilt() const { return Candidates.getFlag(0); }
+ void setIsBuilt(bool Value) { Candidates.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<const IdentifierInfo *> Candidates;
};
void buildLifetimeBoundMacroCache(LifetimeBoundMacroCache &Cache,
ArrayRef<TokenValue> Tokens) {
- if (Cache.IsBuilt)
+ if (Cache.getIsBuilt())
return;
const Preprocessor &PP = S.getPreprocessor();
@@ -552,7 +554,7 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
}
}
}
- Cache.IsBuilt = true;
+ Cache.setIsBuilt(true);
}
StringRef getLastCachedMacroWithSpelling(SourceLocation Loc,
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index bc8a30d4e9dad..9b24f8c513c9b 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4811,7 +4811,7 @@ void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {
void TypoCorrectionConsumer::addNamespaces(
const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces) {
- SearchNamespaces = true;
+ setSearchNamespaces(true);
for (auto KNPair : KnownNamespaces)
Namespaces.addNameSpecifier(KNPair.first);
@@ -4873,7 +4873,7 @@ bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) {
CXXScopeSpec *TempSS = SS.get();
retry_lookup:
LookupPotentialTypoResult(SemaRef, Result, Name, S, TempSS, TempMemberContext,
- EnteringContext,
+ getEnteringContext(),
CorrectionValidator->IsObjCIvarLookup,
Name == Typo && !Candidate.WillReplaceSpecifier());
switch (Result.getResultKind()) {
@@ -4892,7 +4892,7 @@ bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) {
TempMemberContext = nullptr;
goto retry_lookup;
}
- if (SearchNamespaces)
+ if (getSearchNamespaces())
QualifiedResults.push_back(Candidate);
break;
@@ -4907,7 +4907,7 @@ bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) {
Candidate.addCorrectionDecl(TRD);
checkCorrectionVisibility(SemaRef, Candidate);
if (!isCandidateViable(*CorrectionValidator, Candidate)) {
- if (SearchNamespaces)
+ if (getSearchNamespaces())
QualifiedResults.push_back(Candidate);
break;
}
@@ -5321,7 +5321,7 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
const ObjCObjectPointerType *OPT, bool ErrorRecovery) {
if (Diags.hasFatalErrorOccurred() || !getLangOpts().SpellChecking ||
- DisableTypoCorrection)
+ getDisableTypoCorrection())
return nullptr;
// In Microsoft mode, don't perform typo correction in a template member
@@ -5444,9 +5444,9 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
// to search those namespaces.
if (SearchNamespaces) {
// Load any externally-known namespaces.
- if (ExternalSource && !LoadedExternalKnownNamespaces) {
+ if (ExternalSource && !getLoadedExternalKnownNamespaces()) {
SmallVector<NamespaceDecl *, 4> ExternalKnownNamespaces;
- LoadedExternalKnownNamespaces = true;
+ setLoadedExternalKnownNamespaces(true);
ExternalSource->ReadKnownNamespaces(ExternalKnownNamespaces);
for (auto *N : ExternalKnownNamespaces)
KnownNamespaces[N] = true;
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index 7dbb38bbe078e..e2266bad6da22 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -52,7 +52,7 @@ static void checkModuleImportContext(Sema &S, Module *M,
S.Diag(cast<Decl>(DC)->getBeginLoc(),
diag::note_module_import_not_at_top_level)
<< DC;
- } else if (!M->IsExternC && ExternCLoc.isValid()) {
+ } else if (!M->getIsExternC() && ExternCLoc.isValid()) {
S.Diag(ImportLoc, diag::ext_module_import_in_extern_c)
<< M->getFullModuleName();
S.Diag(ExternCLoc, diag::note_extern_c_begins_here);
@@ -481,7 +481,7 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc,
// implementation unit importing its interface). Make this module visible
// and return the import decl to be added to the current TU.
if (Interface) {
- HadImportedNamedModules = true;
+ setHadImportedNamedModules(true);
makeTransitiveImportsVisible(getASTContext(), VisibleModules, Interface,
Mod, ModuleLoc,
@@ -726,7 +726,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
getCurrentModule()->Imports.push_back(Mod);
}
- HadImportedNamedModules = true;
+ setHadImportedNamedModules(true);
return Import;
}
@@ -1617,7 +1617,7 @@ void Sema::checkReferenceToTULocalFromOtherTU(
FunctionDecl *FD, SourceLocation PointOfInstantiation) {
// Checking if a declaration have any reference to TU-local entities in other
// TU is expensive. Try to avoid it as much as possible.
- if (!FD || !HadImportedNamedModules)
+ if (!FD || !getHadImportedNamedModules())
return;
PendingCheckReferenceForTULocal.push_back(
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index a3be416d2da24..bbbeeb66beaf4 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -13,6 +13,7 @@
#include "clang/Sema/SemaOpenMP.h"
#include "clang/AST/ASTConsumer.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "TreeTransform.h"
#include "clang/AST/ASTContext.h"
@@ -202,15 +203,42 @@ class DSAStackTy {
/// 'ordered' clause, the second one is true if the regions has 'ordered'
/// clause, false otherwise.
std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
- bool RegionHasOrderConcurrent = false;
+ bool getRegionHasOrderConcurrent() const {
+ return IteratorVarDecls.getFlag(0);
+ }
+ void setRegionHasOrderConcurrent(bool Value) {
+ IteratorVarDecls.setFlag(0, Value);
+ }
unsigned AssociatedLoops = 1;
- bool HasMutipleLoops = false;
+ bool getHasMutipleLoops() const { return IteratorVarDecls.getFlag(1); }
+ bool setHasMutipleLoops(bool Value) {
+ IteratorVarDecls.setFlag(1, Value);
+ return Value;
+ }
const Decl *PossiblyLoopCounter = nullptr;
- bool NowaitRegion = false;
- bool UntiedRegion = false;
- bool CancelRegion = false;
- bool LoopStart = false;
- bool BodyComplete = false;
+ bool getNowaitRegion() const { return IteratorVarDecls.getFlag(2); }
+ void setNowaitRegion(bool Value) { IteratorVarDecls.setFlag(2, Value); }
+ bool getUntiedRegion() const { return IteratorVarDecls.getFlag(3); }
+ void setUntiedRegion(bool Value) { IteratorVarDecls.setFlag(3, Value); }
+ bool getCancelRegion() const {
+ return ImplicitDefaultFirstprivateFDs.getFlag(0);
+ }
+ bool setCancelRegion(bool Value) {
+ ImplicitDefaultFirstprivateFDs.setFlag(0, Value);
+ return Value;
+ }
+ bool getLoopStart() const {
+ return ImplicitDefaultFirstprivateFDs.getFlag(1);
+ }
+ void setLoopStart(bool Value) {
+ ImplicitDefaultFirstprivateFDs.setFlag(1, Value);
+ }
+ bool getBodyComplete() const {
+ return ImplicitDefaultFirstprivateFDs.getFlag(2);
+ }
+ void setBodyComplete(bool Value) {
+ ImplicitDefaultFirstprivateFDs.setFlag(2, Value);
+ }
SourceLocation PrevScanLocation;
SourceLocation PrevOrderedLocation;
SourceLocation InnerTeamsRegionLoc;
@@ -240,10 +268,10 @@ class DSAStackTy {
: FD(FD), StackLevel(StackLevel), VD(VD) {}
};
/// List of captured fields
- llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
+ llvm::SmallVectorWithFlags<ImplicitDefaultFDInfoTy, 8, 3>
ImplicitDefaultFirstprivateFDs;
Expr *DeclareMapperVar = nullptr;
- SmallVector<VarDecl *, 16> IteratorVarDecls;
+ llvm::SmallVectorWithFlags<VarDecl *, 16, 4> IteratorVarDecls;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
: Directive(DKind), DirectiveName(Name), CurScope(CurScope),
@@ -262,10 +290,16 @@ class DSAStackTy {
/// from current directive.
OpenMPClauseKind ClauseKindMode = OMPC_unknown;
Sema &SemaRef;
- bool ForceCapturing = false;
+ bool getForceCapturing() const { return ConstructTraits.getFlag(0); }
+ void setForceCapturing(bool Value) { ConstructTraits.setFlag(0, Value); }
/// true if all the variables in the target executable directives must be
/// captured by reference.
- bool ForceCaptureByReferenceInTargetExecutable = false;
+ bool getForceCaptureByReferenceInTargetExecutableFlag() const {
+ return ConstructTraits.getFlag(1);
+ }
+ void setForceCaptureByReferenceInTargetExecutableFlag(bool Value) {
+ ConstructTraits.setFlag(1, Value);
+ }
CriticalsWithHintsTy Criticals;
unsigned IgnoredStackElements = 0;
@@ -363,7 +397,7 @@ class DSAStackTy {
SmallVector<SourceLocation, 2> TargetLocations;
SourceLocation AtomicLocation;
/// Vector of declare variant construct traits.
- SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
+ llvm::SmallVectorWithFlags<llvm::omp::TraitProperty, 8, 2> ConstructTraits;
public:
explicit DSAStackTy(Sema &S) : SemaRef(S) {}
@@ -404,18 +438,18 @@ class DSAStackTy {
bool isBodyComplete() const {
const SharingMapTy *Top = getTopOfStackOrNull();
- return Top && Top->BodyComplete;
+ return Top && Top->getBodyComplete();
}
- void setBodyComplete() { getTopOfStack().BodyComplete = true; }
+ void setBodyComplete() { getTopOfStack().setBodyComplete(true); }
- bool isForceVarCapturing() const { return ForceCapturing; }
- void setForceVarCapturing(bool V) { ForceCapturing = V; }
+ bool isForceVarCapturing() const { return getForceCapturing(); }
+ void setForceVarCapturing(bool V) { setForceCapturing(V); }
void setForceCaptureByReferenceInTargetExecutable(bool V) {
- ForceCaptureByReferenceInTargetExecutable = V;
+ setForceCaptureByReferenceInTargetExecutableFlag(V);
}
bool isForceCaptureByReferenceInTargetExecutable() const {
- return ForceCaptureByReferenceInTargetExecutable;
+ return getForceCaptureByReferenceInTargetExecutableFlag();
}
void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
@@ -468,19 +502,19 @@ class DSAStackTy {
void loopInit() {
assert(isOpenMPLoopDirective(getCurrentDirective()) &&
"Expected loop-based directive.");
- getTopOfStack().LoopStart = true;
+ getTopOfStack().setLoopStart(true);
}
/// Start capturing of the variables in the loop context.
void loopStart() {
assert(isOpenMPLoopDirective(getCurrentDirective()) &&
"Expected loop-based directive.");
- getTopOfStack().LoopStart = false;
+ getTopOfStack().setLoopStart(false);
}
/// true, if variables are captured, false otherwise.
bool isLoopStarted() const {
assert(isOpenMPLoopDirective(getCurrentDirective()) &&
"Expected loop-based directive.");
- return !getTopOfStack().LoopStart;
+ return !getTopOfStack().getLoopStart();
}
/// Marks (or clears) declaration as possibly loop counter.
void resetPossibleLoopCounter(const Decl *D = nullptr) {
@@ -925,44 +959,53 @@ class DSAStackTy {
}
/// Marks current region as having an 'order' clause.
void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
- getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
+ [&] {
+ auto PackedFlagValue = HasOrderConcurrent;
+ return getTopOfStack().setRegionHasOrderConcurrent(PackedFlagValue);
+ }();
}
/// Returns true, if parent region is order (has associated
/// 'order' clause), false - otherwise.
bool isParentOrderConcurrent() const {
if (const SharingMapTy *Parent = getSecondOnStackOrNull())
- return Parent->RegionHasOrderConcurrent;
+ return Parent->getRegionHasOrderConcurrent();
return false;
}
/// Marks current region as nowait (it has a 'nowait' clause).
void setNowaitRegion(bool IsNowait = true) {
- getTopOfStack().NowaitRegion = IsNowait;
+ [&] {
+ auto PackedFlagValue = IsNowait;
+ return getTopOfStack().setNowaitRegion(PackedFlagValue);
+ }();
}
/// Returns true, if parent region is nowait (has associated
/// 'nowait' clause), false - otherwise.
bool isParentNowaitRegion() const {
if (const SharingMapTy *Parent = getSecondOnStackOrNull())
- return Parent->NowaitRegion;
+ return Parent->getNowaitRegion();
return false;
}
/// Marks current region as untied (it has a 'untied' clause).
void setUntiedRegion(bool IsUntied = true) {
- getTopOfStack().UntiedRegion = IsUntied;
+ [&] {
+ auto PackedFlagValue = IsUntied;
+ return getTopOfStack().setUntiedRegion(PackedFlagValue);
+ }();
}
/// Return true if current region is untied.
bool isUntiedRegion() const {
const SharingMapTy *Top = getTopOfStackOrNull();
- return Top ? Top->UntiedRegion : false;
+ return Top ? Top->getUntiedRegion() : false;
}
/// Marks parent region as cancel region.
void setParentCancelRegion(bool Cancel = true) {
if (SharingMapTy *Parent = getSecondOnStackOrNull())
- Parent->CancelRegion |= Cancel;
+ Parent->setCancelRegion(Parent->getCancelRegion() | (Cancel));
}
/// Return true if current region has inner cancel construct.
bool isCancelRegion() const {
const SharingMapTy *Top = getTopOfStackOrNull();
- return Top ? Top->CancelRegion : false;
+ return Top ? Top->getCancelRegion() : false;
}
/// Mark that parent region already has scan directive.
@@ -1000,7 +1043,7 @@ class DSAStackTy {
void setAssociatedLoops(unsigned Val) {
getTopOfStack().AssociatedLoops = Val;
if (Val > 1)
- getTopOfStack().HasMutipleLoops = true;
+ getTopOfStack().setHasMutipleLoops(true);
}
/// Return collapse value for region.
unsigned getAssociatedLoops() const {
@@ -1010,7 +1053,7 @@ class DSAStackTy {
/// Returns true if the construct is associated with multiple loops.
bool hasMutipleLoops() const {
const SharingMapTy *Top = getTopOfStackOrNull();
- return Top ? Top->HasMutipleLoops : false;
+ return Top ? Top->getHasMutipleLoops() : false;
}
/// Marks current target region as one with closely nested teams
@@ -8231,7 +8274,7 @@ static bool checkPreferTypeArgs(SemaOpenMP &S, const OMPInteropInfo &Info) {
for (const OMPInteropPref &P : Info.Prefs) {
const Expr *E = P.Fr;
if (!E) {
- assert(Info.HasPreferAttrs && "null Fr requires OMP 6.0 syntax");
+ assert(Info.hasPreferAttrs() && "null Fr requires OMP 6.0 syntax");
} else if (!isDependent(E)) {
if (!E->isIntegerConstantExpr(S.getASTContext()) &&
!isa<StringLiteral>(E)) {
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 2ca12f7a172e7..c4da77e1652e6 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -44,6 +44,7 @@
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -7587,7 +7588,7 @@ void Sema::AddOverloadCandidate(
ConstraintSatisfaction Satisfaction;
if (CheckFunctionConstraints(Function, Satisfaction, /*Loc*/ {},
/*ForOverloadResolution*/ true) ||
- !Satisfaction.IsSatisfied) {
+ !Satisfaction.isSatisfied()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
return;
@@ -8153,7 +8154,7 @@ void Sema::AddMethodCandidate(
ConstraintSatisfaction Satisfaction;
if (CheckFunctionConstraints(Method, Satisfaction, /*Loc*/ {},
/*ForOverloadResolution*/ true) ||
- !Satisfaction.IsSatisfied) {
+ !Satisfaction.isSatisfied()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
return;
@@ -8700,7 +8701,7 @@ void Sema::AddConversionCandidate(
if (Conversion->getTrailingRequiresClause()) {
ConstraintSatisfaction Satisfaction;
if (CheckFunctionConstraints(Conversion, Satisfaction) ||
- !Satisfaction.IsSatisfied) {
+ !Satisfaction.isSatisfied()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
return;
@@ -8995,7 +8996,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
ConstraintSatisfaction Satisfaction;
if (CheckFunctionConstraints(Conversion, Satisfaction, /*Loc*/ {},
/*ForOverloadResolution*/ true) ||
- !Satisfaction.IsSatisfied) {
+ !Satisfaction.isSatisfied()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
return;
@@ -9609,12 +9610,17 @@ class BuiltinOperatorOverloadBuilder {
// Whether a candidate whose parameters are all arithmetic, vector or matrix
// types can be viable. It is viable if there is an arithmetic or enumeral
// candidate type, and every argument might convert to such a type.
- bool ArithmeticCandidatesMayBeViable;
+ bool getArithmeticCandidatesMayBeViable() const {
+ return ArithmeticTypes.getFlag(0);
+ }
+ void setArithmeticCandidatesMayBeViable(bool Value) {
+ ArithmeticTypes.setFlag(0, Value);
+ }
SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes;
OverloadCandidateSet &CandidateSet;
static constexpr int ArithmeticTypesCap = 26;
- SmallVector<CanQualType, ArithmeticTypesCap> ArithmeticTypes;
+ llvm::SmallVectorWithFlags<CanQualType, ArithmeticTypesCap> ArithmeticTypes;
// Define some indices used to iterate over the arithmetic types in
// ArithmeticTypes. The "promoted arithmetic types" are the arithmetic
@@ -9755,13 +9761,13 @@ class BuiltinOperatorOverloadBuilder {
OverloadCandidateSet &CandidateSet)
: S(S), Args(Args),
VisibleTypeConversionsQuals(VisibleTypeConversionsQuals),
- ArithmeticCandidatesMayBeViable(
- HasArithmeticOrEnumeralCandidateType &&
- llvm::all_of(CandidateTypes,
- [](const BuiltinCandidateTypeSet &Types) {
- return Types.mayConvertToArithmetic();
- })),
- CandidateTypes(CandidateTypes), CandidateSet(CandidateSet) {
+ CandidateTypes(CandidateTypes), CandidateSet(CandidateSet),
+ ArithmeticTypes(decltype(this->ArithmeticTypes)::withFlags(unsigned(
+ bool(HasArithmeticOrEnumeralCandidateType &&
+ llvm::all_of(CandidateTypes,
+ [](const BuiltinCandidateTypeSet &Types) {
+ return Types.mayConvertToArithmetic();
+ }))))) {
InitArithmeticTypes();
}
@@ -9785,7 +9791,7 @@ class BuiltinOperatorOverloadBuilder {
// VQ T& operator--(VQ T&);
// T operator--(VQ T&, int);
void addPlusPlusMinusMinusArithmeticOverloads(OverloadedOperatorKind Op) {
- if (!ArithmeticCandidatesMayBeViable)
+ if (!getArithmeticCandidatesMayBeViable())
return;
for (unsigned Arith = 0; Arith < NumArithmeticTypes; ++Arith) {
@@ -9859,7 +9865,7 @@ class BuiltinOperatorOverloadBuilder {
// T operator+(T);
// T operator-(T);
void addUnaryPlusOrMinusArithmeticOverloads() {
- if (!ArithmeticCandidatesMayBeViable)
+ if (!getArithmeticCandidatesMayBeViable())
return;
for (unsigned Arith = FirstPromotedArithmeticType;
@@ -9889,7 +9895,7 @@ class BuiltinOperatorOverloadBuilder {
//
// T operator~(T);
void addUnaryTildePromotedIntegralOverloads() {
- if (!ArithmeticCandidatesMayBeViable)
+ if (!getArithmeticCandidatesMayBeViable())
return;
for (unsigned Int = FirstPromotedIntegralType;
@@ -10112,7 +10118,7 @@ class BuiltinOperatorOverloadBuilder {
// between types L and R.
// Our candidates ignore the first parameter.
void addGenericBinaryArithmeticOverloads() {
- if (!ArithmeticCandidatesMayBeViable)
+ if (!getArithmeticCandidatesMayBeViable())
return;
for (unsigned Left = FirstPromotedArithmeticType;
@@ -10140,7 +10146,7 @@ class BuiltinOperatorOverloadBuilder {
/// * (M2.getElementType(), M2) -> M2
/// * (M2, M2) -> M2 // Only if M2 is not part of CandidateTypes[0].
void addMatrixBinaryArithmeticOverloads() {
- if (!ArithmeticCandidatesMayBeViable)
+ if (!getArithmeticCandidatesMayBeViable())
return;
for (QualType M1 : CandidateTypes[0].matrix_types()) {
@@ -10205,7 +10211,7 @@ class BuiltinOperatorOverloadBuilder {
// where LR is the result of the usual arithmetic conversions
// between types L and R.
void addBinaryBitwiseArithmeticOverloads() {
- if (!ArithmeticCandidatesMayBeViable)
+ if (!getArithmeticCandidatesMayBeViable())
return;
for (unsigned Left = FirstPromotedIntegralType;
@@ -10370,7 +10376,7 @@ class BuiltinOperatorOverloadBuilder {
// VQ L& operator+=(VQ L&, R);
// VQ L& operator-=(VQ L&, R);
void addAssignmentArithmeticOverloads(bool isEqualOp) {
- if (!ArithmeticCandidatesMayBeViable)
+ if (!getArithmeticCandidatesMayBeViable())
return;
for (unsigned Left = 0; Left < NumArithmeticTypes; ++Left) {
@@ -10424,7 +10430,7 @@ class BuiltinOperatorOverloadBuilder {
// VQ L& operator^=(VQ L&, R);
// VQ L& operator|=(VQ L&, R);
void addAssignmentIntegralOverloads() {
- if (!ArithmeticCandidatesMayBeViable)
+ if (!getArithmeticCandidatesMayBeViable())
return;
for (unsigned Left = FirstIntegralType; Left < LastIntegralType; ++Left) {
@@ -11530,7 +11536,7 @@ bool OverloadCandidate::NotValidBecauseConstraintExprHasError() const {
static_cast<TemplateDeductionResult>(DeductionFailure.Result) ==
TemplateDeductionResult::ConstraintsNotSatisfied &&
static_cast<CNSInfo *>(DeductionFailure.Data)
- ->Satisfaction.ContainsErrors;
+ ->Satisfaction.containsErrors();
}
void OverloadCandidateSet::AddDeferredTemplateCandidate(
@@ -11950,7 +11956,7 @@ static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD,
ConstraintSatisfaction Satisfaction;
if (S.CheckFunctionConstraints(FD, Satisfaction, Loc))
return false;
- if (!Satisfaction.IsSatisfied) {
+ if (!Satisfaction.isSatisfied()) {
if (Complain) {
if (InOverloadResolution) {
SmallString<128> TemplateArgString;
@@ -13803,7 +13809,7 @@ void TemplateSpecCandidateSet::NoteCandidates(Sema &S, SourceLocation Loc) {
assert(Cand->Specialization &&
"Non-matching built-in candidates are not added to Cands.");
- Cand->NoteDeductionFailure(S, ForTakingAddress, CandidateSetKind);
+ Cand->NoteDeductionFailure(S, getForTakingAddress(), CandidateSetKind);
}
if (I != E)
@@ -13856,7 +13862,8 @@ class AddressOfFunctionResolver {
const QualType& TargetType;
QualType TargetFunctionType; // Extracted function type from target type
- bool Complain;
+ bool getComplain() const { return Matches.getFlag(0); }
+ void setComplain(bool Value) { Matches.setFlag(0, Value); }
//DeclAccessPair& ResultFunctionAccessPair;
ASTContext& Context;
@@ -13868,21 +13875,22 @@ class AddressOfFunctionResolver {
OverloadExpr::FindResult OvlExprInfo;
OverloadExpr *OvlExpr;
TemplateArgumentListInfo OvlExplicitTemplateArgs;
- SmallVector<std::pair<DeclAccessPair, FunctionDecl*>, 4> Matches;
+ llvm::SmallVectorWithFlags<std::pair<DeclAccessPair, FunctionDecl *>, 4>
+ Matches;
TemplateSpecCandidateSet FailedCandidates;
public:
AddressOfFunctionResolver(Sema &S, Expr *SourceExpr,
const QualType &TargetType, bool Complain)
: S(S), SourceExpr(SourceExpr), TargetType(TargetType),
- Complain(Complain), Context(S.getASTContext()),
+ Context(S.getASTContext()),
TargetTypeIsNonStaticMemberFunction(
!!TargetType->getAs<MemberPointerType>()),
FoundNonTemplateFunction(false),
- StaticMemberFunctionFromBoundPointer(false),
- HasComplained(false),
+ StaticMemberFunctionFromBoundPointer(false), HasComplained(false),
OvlExprInfo(OverloadExpr::find(SourceExpr)),
OvlExpr(OvlExprInfo.Expression),
+ Matches(decltype(this->Matches)::withFlags(unsigned(Complain))),
FailedCandidates(OvlExpr->getNameLoc(), /*ForTakingAddress=*/true) {
ExtractUnqualifiedFunctionTypeFromTargetType();
@@ -14069,8 +14077,8 @@ class AddressOfFunctionResolver {
// If any candidate has a placeholder return type, trigger its deduction
// now.
if (completeFunctionType(S, FunDecl, SourceExpr->getBeginLoc(),
- Complain)) {
- HasComplained |= Complain;
+ getComplain())) {
+ HasComplained |= getComplain();
return false;
}
@@ -14149,7 +14157,7 @@ class AddressOfFunctionResolver {
<< Matches[0].second->getDeclName(),
S.PDiag(diag::note_ovl_candidate)
<< (unsigned)oc_function << (unsigned)ocs_described_template,
- Complain, TargetFunctionType);
+ getComplain(), TargetFunctionType);
if (Result != MatchesCopy.end()) {
// Make it the first and only element
@@ -14157,7 +14165,7 @@ class AddressOfFunctionResolver {
Matches[0].second = cast<FunctionDecl>(*Result);
Matches.resize(1);
} else
- HasComplained |= Complain;
+ HasComplained |= getComplain();
}
void EliminateAllTemplateMatches() {
@@ -14197,12 +14205,18 @@ class AddressOfFunctionResolver {
Results.push_back(Matches[I]);
}
}
- std::swap(Matches, Results);
+ SmallVector<std::pair<DeclAccessPair, FunctionDecl *>, 4> PreviousMatches;
+ PreviousMatches = std::move(Matches);
+ Matches.assign(std::move(Results));
+ Results = std::move(PreviousMatches);
}
void EliminateSuboptimalCudaMatches() {
+ SmallVector<std::pair<DeclAccessPair, FunctionDecl *>, 4> CudaMatches;
+ CudaMatches = std::move(Matches);
S.CUDA().EraseUnwantedMatches(S.getCurFunctionDecl(/*AllowLambda=*/true),
- Matches);
+ CudaMatches);
+ Matches.assign(std::move(CudaMatches));
}
public:
@@ -14868,11 +14882,11 @@ class BuildRecoveryCallExprRAII {
public:
BuildRecoveryCallExprRAII(Sema &S) : SemaRef(S), SatStack(S) {
- assert(SemaRef.IsBuildingRecoveryCallExpr == false);
- SemaRef.IsBuildingRecoveryCallExpr = true;
+ assert(SemaRef.getIsBuildingRecoveryCallExpr() == false);
+ SemaRef.setIsBuildingRecoveryCallExpr(true);
}
- ~BuildRecoveryCallExprRAII() { SemaRef.IsBuildingRecoveryCallExpr = false; }
+ ~BuildRecoveryCallExprRAII() { SemaRef.setIsBuildingRecoveryCallExpr(false); }
};
}
@@ -14894,7 +14908,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
//
// template <typename T> auto foo(T t) -> decltype(foo(t)) {}
// template <typename T> auto foo(T t) -> decltype(foo(&t)) {}
- if (SemaRef.IsBuildingRecoveryCallExpr)
+ if (SemaRef.getIsBuildingRecoveryCallExpr())
return ExprResult();
BuildRecoveryCallExprRAII RCE(SemaRef);
diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp
index 66736670984ef..0d2a1ac19614b 100644
--- a/clang/lib/Sema/SemaPseudoObject.cpp
+++ b/clang/lib/Sema/SemaPseudoObject.cpp
@@ -37,6 +37,7 @@
#include "clang/Sema/Initialization.h"
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaObjC.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
using namespace clang;
using namespace sema;
@@ -186,12 +187,13 @@ namespace {
Sema &S;
unsigned ResultIndex;
SourceLocation GenericLoc;
- bool IsUnique;
- SmallVector<Expr *, 4> Semantics;
+ bool getIsUnique() const { return Semantics.getFlag(0); }
+ void setIsUnique(bool Value) { Semantics.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<Expr *, 4> Semantics;
PseudoOpBuilder(Sema &S, SourceLocation genericLoc, bool IsUnique)
- : S(S), ResultIndex(PseudoObjectExpr::NoResult),
- GenericLoc(genericLoc), IsUnique(IsUnique) {}
+ : S(S), ResultIndex(PseudoObjectExpr::NoResult), GenericLoc(genericLoc),
+ Semantics(decltype(Semantics)::withFlags(unsigned(IsUnique))) {}
virtual ~PseudoOpBuilder() {}
@@ -367,7 +369,7 @@ OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) {
new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(),
e->getValueKind(), e->getObjectKind(),
e);
- if (IsUnique)
+ if (getIsUnique())
captured->setIsUnique(true);
// Make sure we bind that in the semantics.
diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp
index e180b3655bd73..1d40a4bddf348 100644
--- a/clang/lib/Sema/SemaSYCL.cpp
+++ b/clang/lib/Sema/SemaSYCL.cpp
@@ -19,6 +19,7 @@
#include "clang/Sema/Attr.h"
#include "clang/Sema/ParsedAttr.h"
#include "clang/Sema/Sema.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
using namespace clang;
@@ -668,11 +669,12 @@ OutlinedFunctionDecl *BuildSYCLKernelEntryPointOutline(Sema &SemaRef,
class KernelParamsChecker : public ConstSubobjectVisitor<KernelParamsChecker> {
SemaSYCL &SemaSYCLRef;
- bool IsValid = true;
+ bool getIsValid() const { return !ObjectAccessPath.getFlag(0); }
+ void setIsValid(bool Value) { ObjectAccessPath.setFlag(0, !Value); }
using ObjectAccess =
llvm::PointerUnion<const ParmVarDecl *, const CXXBaseSpecifier *,
const FieldDecl *>;
- SmallVector<ObjectAccess, 4> ObjectAccessPath;
+ llvm::SmallVectorWithFlags<ObjectAccess, 4> ObjectAccessPath;
void emitObjectAccessPathNotes() {
for (auto Parent : llvm::reverse(ObjectAccessPath)) {
@@ -748,7 +750,7 @@ class KernelParamsChecker : public ConstSubobjectVisitor<KernelParamsChecker> {
// kernel parameter types contained within the referenced type
// might not be relevant once the programmer addresses the
// invalid use of a reference.
- IsValid = false;
+ setIsValid(false);
return false;
}
return true;
@@ -759,7 +761,7 @@ class KernelParamsChecker : public ConstSubobjectVisitor<KernelParamsChecker> {
ObjectAccessPath.pop_back();
}
- bool isInvalid() { return !IsValid; }
+ bool isInvalid() { return !getIsValid(); }
};
bool verifyKernelParams(FunctionDecl *FD, SemaSYCL &SemaSYCLRef) {
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index a3e3e403188c7..4a7ac65930e03 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3725,7 +3725,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
CurLambda && hasDeducedReturnType(CurLambda->CallOperator);
if (ExprEvalContexts.back().isDiscardedStatementContext() &&
- (HasDeducedReturnType || CurCap->HasImplicitReturnType)) {
+ (HasDeducedReturnType || CurCap->getHasImplicitReturnType())) {
if (RetValExp) {
ExprResult ER =
ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
@@ -3757,7 +3757,7 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
return StmtError();
}
CurCap->ReturnType = FnRetType = FD->getReturnType();
- } else if (CurCap->HasImplicitReturnType) {
+ } else if (CurCap->getHasImplicitReturnType()) {
// For blocks/lambdas with implicit return types, we check each return
// statement individually, and deduce the common return type when the block
// or lambda is completed.
@@ -3874,14 +3874,14 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc,
// If we need to check for the named return value optimization,
// or if we need to infer the return type,
// save the return statement in our scope for later processing.
- if (CurCap->HasImplicitReturnType || NRVOCandidate)
+ if (CurCap->getHasImplicitReturnType() || NRVOCandidate)
FunctionScopes.back()->Returns.push_back(Result);
if (FunctionScopes.back()->FirstReturnLoc.isInvalid())
FunctionScopes.back()->FirstReturnLoc = ReturnLoc;
if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap);
- CurBlock && CurCap->HasImplicitReturnType && RetValExp &&
+ CurBlock && CurCap->getHasImplicitReturnType() && RetValExp &&
RetValExp->containsErrors())
CurBlock->TheDecl->setInvalidDecl();
@@ -4003,7 +4003,7 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
// each return statement. [...] if the type deduced is not the same in
// each deduction, the program is ill-formed.
const LambdaScopeInfo *LambdaSI = getCurLambda();
- if (LambdaSI && LambdaSI->HasImplicitReturnType)
+ if (LambdaSI && LambdaSI->getHasImplicitReturnType())
Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
<< Info.SecondArg << Info.FirstArg << true /*IsLambda*/;
else
@@ -4889,7 +4889,7 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
PushExpressionEvaluationContext(
ExpressionEvaluationContext::PotentiallyEvaluated);
- ExprEvalContexts.back().InImmediateEscalatingFunctionContext = false;
+ ExprEvalContexts.back().setInImmediateEscalatingFunctionContext(false);
}
void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5a61cb852d15e..b0fe4a55901be 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -42,10 +42,12 @@
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/SaveAndRestore.h"
+#include <memory>
#include <optional>
using namespace clang;
@@ -4023,7 +4025,7 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword Keyword,
ClassTemplate->getDeclContext(),
ClassTemplate->getTemplatedDecl()->getBeginLoc(),
ClassTemplate->getLocation(), ClassTemplate, CTAI.CanonicalConverted,
- CTAI.StrictPackMatch, nullptr);
+ CTAI.getStrictPackMatch(), nullptr);
ClassTemplate->AddSpecialization(Decl, InsertToken);
if (ClassTemplate->isOutOfLine())
Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
@@ -4973,7 +4975,7 @@ ExprResult Sema::CheckConceptTemplateId(
SourceRange(SS.isSet() ? SS.getBeginLoc() : ConceptNameInfo.getLoc(),
TemplateArgs->getRAngleLoc()),
Satisfaction, CL);
- Satisfaction.ContainsErrors = Error;
+ Satisfaction.setContainsErrors(Error);
}
if (Error)
@@ -5214,10 +5216,11 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S,
return TNK_Non_template;
}
-bool Sema::CheckTemplateTypeArgument(
- TemplateTypeParmDecl *Param, TemplateArgumentLoc &AL,
- SmallVectorImpl<TemplateArgument> &SugaredConverted,
- SmallVectorImpl<TemplateArgument> &CanonicalConverted) {
+bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
+ TemplateArgumentLoc &AL,
+ CheckTemplateArgumentInfo &CTAI) {
+ auto &SugaredConverted = CTAI.SugaredConverted;
+ auto &CanonicalConverted = CTAI.CanonicalConverted;
const TemplateArgument &Arg = AL.getArgument();
QualType ArgType;
TypeSourceInfo *TSI = nullptr;
@@ -5594,8 +5597,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
CheckTemplateArgumentKind CTAK) {
// Check template type parameters.
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
- return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI.SugaredConverted,
- CTAI.CanonicalConverted);
+ return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI);
const TemplateArgument &Arg = ArgLoc.getArgument();
// Check non-type template parameters.
@@ -5619,7 +5621,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
return AT && AT->isDecltypeAuto() == DecltypeAuto &&
AT->getDeducedType().isNull();
};
- if (CTAI.PartialOrdering &&
+ if (CTAI.getPartialOrdering() &&
isUndeducedAuto(NTTPType, /*DecltypeAuto=*/false) &&
isUndeducedAuto(getTypeOfConstantTemplateParameter(Arg),
/*DecltypeAuto=*/true))
@@ -5659,7 +5661,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
TemplateArgument SugaredResult, CanonicalResult;
ExprResult Res = CheckTemplateArgument(
NTTP, NTTPType, E, SugaredResult, CanonicalResult,
- /*StrictCheck=*/CTAI.MatchingTTP || CTAI.PartialOrdering, CTAK);
+ /*StrictCheck=*/CTAI.getMatchingTTP() || CTAI.getPartialOrdering(),
+ CTAK);
// If the current template argument causes an error, give up now.
if (Res.isInvalid())
return nullptr;
@@ -5740,7 +5743,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
TemplateArgument SugaredResult, CanonicalResult;
E = CheckTemplateArgument(
NTTP, NTTPType, E.get(), SugaredResult, CanonicalResult,
- /*StrictCheck=*/CTAI.PartialOrdering, CTAK_Specified);
+ /*StrictCheck=*/CTAI.getPartialOrdering(), CTAK_Specified);
if (E.isInvalid())
return true;
@@ -5833,16 +5836,19 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
llvm_unreachable("Should never see a NULL template argument here");
case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- if (CheckTemplateTemplateArgument(TempParm, Params, ArgLoc,
- CTAI.PartialOrdering,
- &CTAI.StrictPackMatch))
+ case TemplateArgument::TemplateExpansion: {
+ bool StrictPackMatch = CTAI.getStrictPackMatch();
+ bool InvalidArgument = CheckTemplateTemplateArgument(
+ TempParm, Params, ArgLoc, CTAI.getPartialOrdering(), &StrictPackMatch);
+ CTAI.setStrictPackMatch(StrictPackMatch);
+ if (InvalidArgument)
return true;
CTAI.SugaredConverted.push_back(Arg);
CTAI.CanonicalConverted.push_back(
Context.getCanonicalTemplateArgument(Arg));
break;
+ }
case TemplateArgument::Expression:
case TemplateArgument::Type: {
@@ -6033,7 +6039,7 @@ bool Sema::CheckTemplateArgumentList(
!(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param);
bool ArgIsExpansion = ArgLoc.getArgument().isPackExpansion();
- if (ArgIsExpansion && CTAI.MatchingTTP) {
+ if (ArgIsExpansion && CTAI.getMatchingTTP()) {
SmallVector<TemplateArgument, 4> Args(ParamEnd - Param);
for (TemplateParameterList::iterator First = Param; Param != ParamEnd;
++Param) {
@@ -6043,8 +6049,20 @@ bool Sema::CheckTemplateArgumentList(
getExpandedPackSize(*Param))
Arg = Arg.getPackExpansionPattern();
TemplateArgumentLoc NewArgLoc(Arg, ArgLoc.getLocInfo());
- SaveAndRestore _1(CTAI.PartialOrdering, false);
- SaveAndRestore _2(CTAI.MatchingTTP, true);
+ auto _1 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getPartialOrdering();
+ PackedFlagOwner->setPartialOrdering(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setPartialOrdering(PackedFlagOld);
+ });
+ }();
+ auto _2 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getMatchingTTP();
+ PackedFlagOwner->setMatchingTTP(true);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setMatchingTTP(PackedFlagOld);
+ });
+ }();
if (CheckTemplateArgument(*Param, NewArgLoc, Template, TemplateLoc,
RAngleLoc, SugaredArgumentPack.size(), CTAI,
CTAK_Specified))
@@ -6059,7 +6077,13 @@ bool Sema::CheckTemplateArgumentList(
TemplateArgument::CreatePackCopy(Context, Args),
TemplateArgumentLocInfo(Context, ArgLoc.getLocation()));
} else {
- SaveAndRestore _1(CTAI.PartialOrdering, false);
+ auto _1 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getPartialOrdering();
+ PackedFlagOwner->setPartialOrdering(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setPartialOrdering(PackedFlagOld);
+ });
+ }();
if (CheckTemplateArgument(*Param, ArgLoc, Template, TemplateLoc,
RAngleLoc, SugaredArgumentPack.size(), CTAI,
CTAK_Specified))
@@ -6089,7 +6113,7 @@ bool Sema::CheckTemplateArgumentList(
// We're now done with this argument.
++ArgIdx;
- if (ArgIsExpansion && (CTAI.MatchingTTP || NonPackParameter)) {
+ if (ArgIsExpansion && (CTAI.getMatchingTTP() || NonPackParameter)) {
// Directly convert the remaining arguments, because we don't know what
// parameters they'll match up with.
@@ -6206,9 +6230,27 @@ bool Sema::CheckTemplateArgumentList(
if (Inst.isInvalid())
return true;
- SaveAndRestore _1(CTAI.PartialOrdering, false);
- SaveAndRestore _2(CTAI.MatchingTTP, false);
- SaveAndRestore _3(CTAI.StrictPackMatch, {});
+ auto _1 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getPartialOrdering();
+ PackedFlagOwner->setPartialOrdering(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setPartialOrdering(PackedFlagOld);
+ });
+ }();
+ auto _2 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getMatchingTTP();
+ PackedFlagOwner->setMatchingTTP(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setMatchingTTP(PackedFlagOld);
+ });
+ }();
+ auto _3 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getStrictPackMatch();
+ PackedFlagOwner->setStrictPackMatch(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setStrictPackMatch(PackedFlagOld);
+ });
+ }();
// Check the default template argument.
if (CheckTemplateArgument(*Param, Arg, Template, TemplateLoc, RAngleLoc, 0,
CTAI, CTAK_Specified))
@@ -6232,7 +6274,7 @@ bool Sema::CheckTemplateArgumentList(
// pack expansions; they might be empty. This can happen even if
// PartialTemplateArgs is false (the list of arguments is complete but
// still dependent).
- if (CTAI.MatchingTTP ||
+ if (CTAI.getMatchingTTP() ||
(CurrentInstantiationScope &&
CurrentInstantiationScope->getPartiallySubstitutedPack())) {
while (ArgIdx < NumArgs &&
@@ -9041,7 +9083,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
// this explicit specialization or friend declaration.
Specialization = ClassTemplateSpecializationDecl::Create(
Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc,
- ClassTemplate, CTAI.CanonicalConverted, CTAI.StrictPackMatch, PrevDecl);
+ ClassTemplate, CTAI.CanonicalConverted, CTAI.getStrictPackMatch(),
+ PrevDecl);
Specialization->setTemplateArgsAsWritten(TemplateArgs);
SetNestedNameSpecifier(*this, Specialization, SS);
if (TemplateParameterLists.size() > 0) {
@@ -9980,7 +10023,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
(CheckFunctionConstraints(Method, Satisfaction,
/*UsageLoc=*/Member->getLocation(),
/*ForOverloadResolution=*/true) ||
- !Satisfaction.IsSatisfied))
+ !Satisfaction.isSatisfied()))
continue;
Candidates.addDecl(Candidate);
@@ -10498,7 +10541,8 @@ DeclResult Sema::ActOnExplicitInstantiation(
// this explicit specialization.
Specialization = ClassTemplateSpecializationDecl::Create(
Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc,
- ClassTemplate, CTAI.CanonicalConverted, CTAI.StrictPackMatch, PrevDecl);
+ ClassTemplate, CTAI.CanonicalConverted, CTAI.getStrictPackMatch(),
+ PrevDecl);
SetNestedNameSpecifier(*this, Specialization, SS);
// A MSInheritanceAttr attached to the previous declaration must be
@@ -10564,7 +10608,7 @@ DeclResult Sema::ActOnExplicitInstantiation(
if (!Def)
InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK,
/*Complain=*/true,
- CTAI.StrictPackMatch);
+ CTAI.getStrictPackMatch());
else if (TSK == TSK_ExplicitInstantiationDefinition) {
MarkVTableUsed(TemplateNameLoc, Specialization, true);
Specialization->setPointOfInstantiation(Def->getPointOfInstantiation());
@@ -11046,7 +11090,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
if (Method->getTrailingRequiresClause() &&
(CheckFunctionConstraints(Method, S, D.getIdentifierLoc(),
/*ForOverloadResolution=*/true) ||
- !S.IsSatisfied)) {
+ !S.isSatisfied())) {
C.Viable = false;
C.FailureKind = ovl_fail_constraints_not_satisfied;
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 90724e1d01cb2..cae5be74468fe 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -48,15 +48,18 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include <algorithm>
#include <cassert>
+#include <memory>
#include <optional>
#include <tuple>
#include <type_traits>
@@ -870,8 +873,9 @@ class PackDeductionScope {
bool DeducePackIfNotAlreadyDeduced = false,
bool FinishingDeduction = false)
: S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info),
- DeducePackIfNotAlreadyDeduced(DeducePackIfNotAlreadyDeduced),
- FinishingDeduction(FinishingDeduction) {
+ Packs(decltype(this->Packs)::withFlags(
+ (unsigned(DeducePackIfNotAlreadyDeduced) << 1) |
+ (unsigned(FinishingDeduction) << 3))) {
unsigned NumNamedPacks = addPacks(Pattern);
finishConstruction(NumNamedPacks);
}
@@ -889,9 +893,9 @@ class PackDeductionScope {
void addPack(unsigned Index) {
// Save the deduced template argument for the parameter pack expanded
// by this pack expansion, then clear out the deduction.
- DeducedFromEarlierParameter = !Deduced[Index].isNull();
+ setDeducedFromEarlierParameter(!Deduced[Index].isNull());
DeducedPack Pack(Index);
- if (!FinishingDeduction) {
+ if (!getFinishingDeduction()) {
Pack.Saved = Deduced[Index];
Deduced[Index] = TemplateArgument();
}
@@ -985,12 +989,12 @@ class PackDeductionScope {
for (unsigned I = 0; I != NumNamedPacks; ++I) {
if (Packs[I].Index >= Info.getNumExplicitArgs()) {
IsExpanded = false;
- IsPartiallyExpanded = false;
+ setIsPartiallyExpanded(false);
break;
}
if (PartialPackDepthIndex ==
std::make_pair(Info.getDeducedDepth(), Packs[I].Index)) {
- IsPartiallyExpanded = true;
+ setIsPartiallyExpanded(true);
}
}
@@ -998,7 +1002,7 @@ class PackDeductionScope {
// If we partially expanded, this is the number of partial arguments.
// FIXME: `&& FixedNumExpansions` is a workaround for UB described in
// https://github.com/llvm/llvm-project/issues/100095
- if (IsPartiallyExpanded)
+ if (getIsPartiallyExpanded())
PackElements += NumPartialPackArgs;
else if (IsExpanded && FixedNumExpansions)
PackElements += *FixedNumExpansions;
@@ -1037,12 +1041,12 @@ class PackDeductionScope {
/// Determine whether this pack has already been deduced from a previous
/// argument.
bool isDeducedFromEarlierParameter() const {
- return DeducedFromEarlierParameter;
+ return getDeducedFromEarlierParameter();
}
/// Determine whether this pack has already been partially expanded into a
/// sequence of (prior) function parameters / template arguments.
- bool isPartiallyExpanded() { return IsPartiallyExpanded; }
+ bool isPartiallyExpanded() { return getIsPartiallyExpanded(); }
/// Determine whether this pack expansion scope has a known, fixed arity.
/// This happens if it involves a pack from an outer template that has
@@ -1061,7 +1065,7 @@ class PackDeductionScope {
// Capture the deduced template arguments for each parameter pack expanded
// by this pack expansion, add them to the list of arguments we've deduced
// for that pack, then clear out the deduced argument.
- if (!FinishingDeduction) {
+ if (!getFinishingDeduction()) {
for (auto &Pack : Packs) {
DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
if (!Pack.New.empty() || !DeducedArg.isNull()) {
@@ -1084,13 +1088,13 @@ class PackDeductionScope {
/// producing the argument packs and checking for consistency with prior
/// deductions.
TemplateDeductionResult finish() {
- if (FinishingDeduction)
+ if (getFinishingDeduction())
return TemplateDeductionResult::Success;
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
for (auto &Pack : Packs) {
// Put back the old value for this pack.
- if (!FinishingDeduction)
+ if (!getFinishingDeduction())
Deduced[Pack.Index] = Pack.Saved;
// Always make sure the size of this pack is correct, even if we didn't
@@ -1144,7 +1148,7 @@ class PackDeductionScope {
// Check the new pack matches any previous value.
DeducedTemplateArgument OldPack = *Loc;
DeducedTemplateArgument Result = checkDeducedTemplateArguments(
- S.Context, OldPack, NewPack, DeducePackIfNotAlreadyDeduced);
+ S.Context, OldPack, NewPack, getDeducePackIfNotAlreadyDeduced());
Info.AggregateDeductionCandidateHasMismatchedArity =
OldPack.getKind() == TemplateArgument::Pack &&
@@ -1188,14 +1192,18 @@ class PackDeductionScope {
SmallVectorImpl<DeducedTemplateArgument> &Deduced;
TemplateDeductionInfo &Info;
unsigned PackElements = 0;
- bool IsPartiallyExpanded = false;
- bool DeducePackIfNotAlreadyDeduced = false;
- bool DeducedFromEarlierParameter = false;
- bool FinishingDeduction = false;
+ bool getIsPartiallyExpanded() const { return Packs.getFlag(0); }
+ void setIsPartiallyExpanded(bool Value) { Packs.setFlag(0, Value); }
+ bool getDeducePackIfNotAlreadyDeduced() const { return Packs.getFlag(1); }
+ void setDeducePackIfNotAlreadyDeduced(bool Value) { Packs.setFlag(1, Value); }
+ bool getDeducedFromEarlierParameter() const { return Packs.getFlag(2); }
+ void setDeducedFromEarlierParameter(bool Value) { Packs.setFlag(2, Value); }
+ bool getFinishingDeduction() const { return Packs.getFlag(3); }
+ void setFinishingDeduction(bool Value) { Packs.setFlag(3, Value); }
/// The number of expansions, if we have a fully-expanded pack in this scope.
UnsignedOrNone FixedNumExpansions = std::nullopt;
- SmallVector<DeducedPack, 2> Packs;
+ llvm::SmallVectorWithFlags<DeducedPack, 2, 4> Packs;
};
} // namespace
@@ -1496,8 +1504,13 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD,
// We iterate over this later, so we have to use MapVector to ensure
// determinism.
struct MatchValue {
- SmallVector<DeducedTemplateArgument, 8> Deduced;
- bool HasDeducedAnyParam;
+ llvm::SmallVectorWithFlags<DeducedTemplateArgument, 8> Deduced;
+ bool getHasDeducedAnyParam() const { return Deduced.getFlag(0); }
+ void setHasDeducedAnyParam(bool Value) { Deduced.setFlag(0, Value); }
+
+ MatchValue(SmallVector<DeducedTemplateArgument, 8> Deduced,
+ bool HasDeducedAnyParam)
+ : Deduced(unsigned(HasDeducedAnyParam), std::move(Deduced)) {}
};
llvm::MapVector<const CXXRecordDecl *, MatchValue> Matches;
@@ -1563,8 +1576,11 @@ DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD,
if (Matches.size() > 1)
return TemplateDeductionResult::MiscellaneousDeductionFailure;
- std::swap(Matches.front().second.Deduced, Deduced);
- if (bool HasDeducedAnyParamCopy = Matches.front().second.HasDeducedAnyParam;
+ Deduced.assign(
+ std::make_move_iterator(Matches.front().second.Deduced.begin()),
+ std::make_move_iterator(Matches.front().second.Deduced.end()));
+ if (bool HasDeducedAnyParamCopy =
+ Matches.front().second.getHasDeducedAnyParam();
HasDeducedAnyParamCopy && HasDeducedAnyParam)
*HasDeducedAnyParam = HasDeducedAnyParamCopy;
return TemplateDeductionResult::Success;
@@ -2959,8 +2975,20 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
TemplateArgumentLoc ArgLoc =
S.getTrivialTemplateArgumentLoc(Arg, QualType(), Info.getLocation());
- SaveAndRestore _1(CTAI.MatchingTTP, false);
- SaveAndRestore _2(CTAI.StrictPackMatch, false);
+ auto _1 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getMatchingTTP();
+ PackedFlagOwner->setMatchingTTP(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setMatchingTTP(PackedFlagOld);
+ });
+ }();
+ auto _2 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getStrictPackMatch();
+ PackedFlagOwner->setStrictPackMatch(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setStrictPackMatch(PackedFlagOld);
+ });
+ }();
// Check the template argument, converting it as necessary.
auto Res = S.CheckTemplateArgument(
Param, ArgLoc, Template, Template->getLocation(),
@@ -2969,7 +2997,7 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound
: Sema::CTAK_Deduced)
: Sema::CTAK_Specified);
- if (CTAI.StrictPackMatch)
+ if (CTAI.getStrictPackMatch())
Info.setStrictPackMatch();
return Res;
};
@@ -3160,9 +3188,27 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments(
: TemplateDeductionResult::Incomplete;
}
- SaveAndRestore _1(CTAI.PartialOrdering, false);
- SaveAndRestore _2(CTAI.MatchingTTP, false);
- SaveAndRestore _3(CTAI.StrictPackMatch, false);
+ auto _1 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getPartialOrdering();
+ PackedFlagOwner->setPartialOrdering(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setPartialOrdering(PackedFlagOld);
+ });
+ }();
+ auto _2 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getMatchingTTP();
+ PackedFlagOwner->setMatchingTTP(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setMatchingTTP(PackedFlagOld);
+ });
+ }();
+ auto _3 = [PackedFlagOwner = std::addressof(CTAI)] {
+ const bool PackedFlagOld = PackedFlagOwner->getStrictPackMatch();
+ PackedFlagOwner->setStrictPackMatch(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setStrictPackMatch(PackedFlagOld);
+ });
+ }();
// Check whether we can actually use the default argument.
if (S.CheckTemplateArgument(
Param, DefArg, TD, TD->getLocation(), TD->getSourceRange().getEnd(),
@@ -3239,7 +3285,7 @@ CheckDeducedArgumentConstraints(Sema &S, NamedDecl *Template,
if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, MLTAL,
Info.getLocation(),
Info.AssociatedConstraintsSatisfaction) ||
- !Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
+ !Info.AssociatedConstraintsSatisfaction.isSatisfied()) {
Info.reset(
TemplateArgumentList::CreateCopy(S.Context, SugaredDeducedArgs),
TemplateArgumentList::CreateCopy(S.Context, CanonicalDeducedArgs));
@@ -4010,7 +4056,7 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
Info.getLocation(),
FunctionTemplate->getCanonicalDecl()->getTemplatedDecl(),
CTAI.CanonicalConverted, Info.AssociatedConstraintsSatisfaction) ||
- !Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
+ !Info.AssociatedConstraintsSatisfaction.isSatisfied()) {
Info.reset(Info.takeSugared(), TemplateArgumentList::CreateCopy(
Context, CTAI.CanonicalConverted));
return TemplateDeductionResult::ConstraintsNotSatisfied;
@@ -4057,7 +4103,7 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
if (CheckFunctionTemplateConstraints(
Info.getLocation(), Specialization, CTAI.CanonicalConverted,
Info.AssociatedConstraintsSatisfaction) ||
- !Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
+ !Info.AssociatedConstraintsSatisfaction.isSatisfied()) {
Info.reset(Info.takeSugared(), TemplateArgumentList::CreateCopy(
Context, CTAI.CanonicalConverted));
return TemplateDeductionResult::ConstraintsNotSatisfied;
@@ -4263,7 +4309,7 @@ bool Sema::DeduceTemplateArguments(
if (CheckConstraintSatisfaction(PatternCTD, Constraints, DeducedArgs,
SourceRange(Loc),
Info.AssociatedConstraintsSatisfaction) ||
- !Info.AssociatedConstraintsSatisfaction.IsSatisfied ||
+ !Info.AssociatedConstraintsSatisfaction.isSatisfied() ||
Trap.hasErrorOccurred()) {
SmallVector<TemplateArgument, 4> CanonicalCandidateArgs;
CanonicalCandidateArgs.reserve(CandidateArgs.size());
@@ -5396,7 +5442,7 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
Concept, AssociatedConstraint(Concept->getConstraintExpr()), MLTAL,
TypeLoc.getLocalSourceRange(), Satisfaction))
return true;
- if (!Satisfaction.IsSatisfied) {
+ if (!Satisfaction.isSatisfied()) {
std::string Buf;
llvm::raw_string_ostream OS(Buf);
OS << "'" << Concept->getName();
@@ -6763,7 +6809,7 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
return false;
PArgs = std::move(CTAI.SugaredConverted);
if (StrictPackMatch)
- *StrictPackMatch |= CTAI.StrictPackMatch;
+ *StrictPackMatch |= CTAI.getStrictPackMatch();
}
// Determine whether P1 is at least as specialized as P2.
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 036642f22bd8c..6309606a18e8e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1788,7 +1788,7 @@ namespace {
ExprResult TransformLambdaExpr(LambdaExpr *E) {
// Do not rebuild lambdas to avoid creating a new type.
// Lambdas have already been processed inside their eval contexts.
- if (SemaRef.RebuildingImmediateInvocation)
+ if (SemaRef.getRebuildingImmediateInvocation())
return E;
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true,
/*InstantiatingLambdaOrBlock=*/true);
@@ -2837,7 +2837,7 @@ TemplateInstantiator::TransformNestedRequirement(
auto NestedReqWithDiag = [&C, this](Expr *E,
ConstraintSatisfaction Satisfaction) {
- Satisfaction.IsSatisfied = false;
+ Satisfaction.setIsSatisfied(false);
SmallString<128> Entity;
llvm::raw_svector_ostream OS(Entity);
E->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
@@ -2891,7 +2891,7 @@ TemplateInstantiator::TransformNestedRequirement(
// FIXME: const correctness
// MLTAL might be dependent.
if (!NewConstraint) {
- if (!Satisfaction.IsSatisfied)
+ if (!Satisfaction.isSatisfied())
return NestedReqWithDiag(Constraint, Satisfaction);
NewConstraint = Constraint;
@@ -4229,7 +4229,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
if (Function->getTrailingRequiresClause()) {
ConstraintSatisfaction Satisfaction;
if (CheckFunctionConstraints(Function, Satisfaction) ||
- !Satisfaction.IsSatisfied) {
+ !Satisfaction.isSatisfied()) {
continue;
}
}
@@ -4796,7 +4796,7 @@ LocalInstantiationScope::getInstantiationOfIfExists(const Decl *D) {
} while (CheckD);
// If we aren't combined with our outer scope, we're done.
- if (!Current->CombineWithOuterScope)
+ if (!Current->getCombineWithOuterScope())
break;
}
@@ -4844,7 +4844,7 @@ void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
#ifndef NDEBUG
// It should not be present in any surrounding scope either.
LocalInstantiationScope *Current = this;
- while (Current->CombineWithOuterScope && Current->Outer) {
+ while (Current->getCombineWithOuterScope() && Current->Outer) {
Current = Current->Outer;
assert(!Current->LocalDecls.contains(D) &&
"Instantiated local in inner and outer scopes");
@@ -4869,7 +4869,7 @@ void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) {
#ifndef NDEBUG
// This should be the first time we've been told about this decl.
for (LocalInstantiationScope *Current = this;
- Current && Current->CombineWithOuterScope; Current = Current->Outer)
+ Current && Current->getCombineWithOuterScope(); Current = Current->Outer)
assert(!Current->LocalDecls.contains(D) &&
"Creating local pack after instantiation of local");
#endif
@@ -4920,7 +4920,7 @@ NamedDecl *LocalInstantiationScope::getPartiallySubstitutedPack(
return Current->PartiallySubstitutedPack;
}
- if (!Current->CombineWithOuterScope)
+ if (!Current->getCombineWithOuterScope())
break;
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b4881d0c6db5c..737459155d16e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -32,7 +32,7 @@
#include "clang/Sema/SemaOpenMP.h"
#include "clang/Sema/SemaSwift.h"
#include "clang/Sema/Template.h"
-#include "llvm/Support/SaveAndRestore.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/TimeProfiler.h"
#include <optional>
@@ -578,8 +578,8 @@ static void instantiateOMPDeclareVariantAttr(
NeedDeviceAddrExprs.push_back(ER.get());
}
for (OMPInteropInfo &II : Attr.appendArgs()) {
- OMPInteropInfo Info(II.IsTarget, II.IsTargetSync);
- Info.HasPreferAttrs = II.HasPreferAttrs;
+ OMPInteropInfo Info(II.isTarget(), II.isTargetSync());
+ Info.setPreferAttrs(II.hasPreferAttrs());
for (const OMPInteropPref &P : II.Prefs) {
Expr *SubstFr = nullptr;
if (P.Fr) {
@@ -2784,7 +2784,10 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
// merged with the local instantiation scope for the function template
// itself.
LocalInstantiationScope Scope(SemaRef);
- llvm::SaveAndRestore RAII(EvaluateConstraints, false);
+ llvm::scope_exit RAII([this, Old = getEvaluateConstraintsFlag()] {
+ setEvaluateConstraintsFlag(Old);
+ });
+ setEvaluateConstraintsFlag(false);
TemplateParameterList *TempParams = D->getTemplateParameters();
TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
@@ -3854,7 +3857,7 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
// with the corresponding auto-typed parameter as it might reference
// other parameters.
if (SemaRef.SubstTypeConstraint(Inst, TC, TemplateArgs,
- EvaluateConstraints))
+ getEvaluateConstraintsFlag()))
return nullptr;
}
}
@@ -4842,7 +4845,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl::Create(
SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(),
D->getLocation(), InstClassTemplate, CTAI.CanonicalConverted,
- CTAI.StrictPackMatch, PrevDecl);
+ CTAI.getStrictPackMatch(), PrevDecl);
InstD->setTemplateArgsAsWritten(InstTemplateArgs);
// Add this partial specialization to the set of class template partial
@@ -5148,7 +5151,7 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
return nullptr;
Expr *InstRequiresClause = L->getRequiresClause();
- if (InstRequiresClause && EvaluateConstraints) {
+ if (InstRequiresClause && getEvaluateConstraintsFlag()) {
ExprResult E =
SemaRef.SubstConstraintExpr(InstRequiresClause, TemplateArgs);
if (E.isInvalid())
@@ -5166,7 +5169,10 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
bool TemplateDeclInstantiator::SubstTemplateParameterLists(
ArrayRef<TemplateParameterList *> TPLs,
SmallVectorImpl<TemplateParameterList *> &InstTPLs) {
- llvm::SaveAndRestore RAII(EvaluateConstraints, false);
+ llvm::scope_exit RAII([this, Old = getEvaluateConstraintsFlag()] {
+ setEvaluateConstraintsFlag(Old);
+ });
+ setEvaluateConstraintsFlag(false);
for (TemplateParameterList *L : TPLs) {
TemplateParameterList *InstParams = SubstTemplateParams(L);
if (!InstParams)
@@ -5447,7 +5453,7 @@ TypeSourceInfo *TemplateDeclInstantiator::SubstFunctionType(
TypeSourceInfo *NewTInfo = SemaRef.SubstFunctionDeclType(
OldTInfo, TemplateArgs, D->getTypeSpecStartLoc(), D->getDeclName(),
- ThisContext, ThisTypeQuals, EvaluateConstraints);
+ ThisContext, ThisTypeQuals, getEvaluateConstraintsFlag());
if (!NewTInfo)
return nullptr;
@@ -5505,7 +5511,7 @@ TypeSourceInfo *TemplateDeclInstantiator::SubstFunctionType(
ParmVarDecl *Parm = SemaRef.SubstParmVarDecl(
OldParam, TemplateArgs, /*indexAdjustment=*/0,
/*NumExpansions=*/std::nullopt,
- /*ExpectParameterPack=*/false, EvaluateConstraints);
+ /*ExpectParameterPack=*/false, getEvaluateConstraintsFlag());
if (!Parm)
return nullptr;
Params.push_back(Parm);
@@ -6343,8 +6349,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
VarTemplateDecl *VarTemplate, VarDecl *FromVar,
const TemplateArgumentList *PartialSpecArgs,
- SmallVectorImpl<TemplateArgument> &Converted,
- SourceLocation PointOfInstantiation, LateInstantiatedAttrVec *LateAttrs,
+ ArrayRef<TemplateArgument> Converted, SourceLocation PointOfInstantiation,
+ LateInstantiatedAttrVec *LateAttrs,
LocalInstantiationScope *StartingScope) {
if (FromVar->isInvalidDecl())
return nullptr;
@@ -6569,10 +6575,18 @@ void Sema::InstantiateVariableInitializer(
EnterExpressionEvaluationContext Evaluated(
*this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var,
ExpressionEvaluationContextRecord::EK_VariableInit);
- currentEvaluationContext().InLifetimeExtendingContext =
- parentEvaluationContext().InLifetimeExtendingContext;
- currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
- parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
+ [&] {
+ auto PackedFlagValue_ =
+ parentEvaluationContext().getInLifetimeExtendingContext();
+ return currentEvaluationContext().setInLifetimeExtendingContext(
+ PackedFlagValue_);
+ }();
+ [&] {
+ auto PackedFlagValue_ =
+ parentEvaluationContext().getRebuildDefaultArgOrDefaultInit();
+ return currentEvaluationContext().setRebuildDefaultArgOrDefaultInit(
+ PackedFlagValue_);
+ }();
// Set DeclForInitializer for this variable so DiagIfReachable can properly
// suppress runtime diagnostics for constexpr/static member variables
@@ -7408,7 +7422,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
// argument deduction in the process of rebuilding immediate
// expressions. (Because the default argument that involves a lambda
// is untransformed and thus could be dependent at this point.)
- assert(SemaRef.RebuildingImmediateInvocation ||
+ assert(SemaRef.getRebuildingImmediateInvocation() ||
CodeSynthesisContexts.back().Kind ==
CodeSynthesisContext::BuildingDeductionGuides);
// Return a nullptr as a sentinel value, we handle it properly in
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 2d6e75bd77b40..d0c7498f6e494 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -491,7 +491,7 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
}
if (!EnclosingStmtExpr) {
- CSI->ContainsUnexpandedParameterPack = true;
+ CSI->setContainsUnexpandedParameterPack(true);
return false;
}
} else {
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 3d444bfabc8c3..c2a7b041943ca 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -43,6 +43,7 @@
#include "clang/Sema/Template.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/ErrorHandling.h"
@@ -200,7 +201,7 @@ namespace {
/// A list of attributes to diagnose the uselessness of when the
/// processing is complete.
- SmallVector<ParsedAttr *, 2> ignoredTypeAttrs;
+ llvm::SmallVectorWithFlags<ParsedAttr *, 2, 3> ignoredTypeAttrs;
/// Attributes corresponding to AttributedTypeLocs that we have not yet
/// populated.
@@ -210,7 +211,10 @@ namespace {
// properly.
using TypeAttrPair = std::pair<const AttributedType*, const Attr*>;
SmallVector<TypeAttrPair, 8> AttrsForTypes;
- bool AttrsForTypesSorted = true;
+ bool getAttrsForTypesSorted() const { return !ignoredTypeAttrs.getFlag(0); }
+ void setAttrsForTypesSorted(bool Value) {
+ ignoredTypeAttrs.setFlag(0, !Value);
+ }
/// MacroQualifiedTypes mapping to macro expansion locations that will be
/// stored in a MacroQualifiedTypeLoc.
@@ -218,17 +222,24 @@ namespace {
/// Flag to indicate we parsed a noderef attribute. This is used for
/// validating that noderef was used on a pointer or array.
- bool parsedNoDeref;
+ bool getParsedNoDerefFlag() const { return ignoredTypeAttrs.getFlag(1); }
+ void setParsedNoDerefFlag(bool Value) {
+ ignoredTypeAttrs.setFlag(1, Value);
+ }
// Flag to indicate that we already parsed a HLSL parameter modifier
// attribute. This prevents double-mutating the type.
- bool ParsedHLSLParamMod;
+ bool getParsedHLSLParamModFlag() const {
+ return ignoredTypeAttrs.getFlag(2);
+ }
+ void setParsedHLSLParamModFlag(bool Value) {
+ ignoredTypeAttrs.setFlag(2, Value);
+ }
public:
TypeProcessingState(Sema &sema, Declarator &declarator)
: sema(sema), declarator(declarator),
- chunkIndex(declarator.getNumTypeObjects()), parsedNoDeref(false),
- ParsedHLSLParamMod(false) {}
+ chunkIndex(declarator.getNumTypeObjects()) {}
Sema &getSema() const {
return sema;
@@ -288,7 +299,7 @@ namespace {
QualType T =
sema.Context.getAttributedType(A, ModifiedType, EquivType);
AttrsForTypes.push_back({cast<AttributedType>(T.getTypePtr()), A});
- AttrsForTypesSorted = false;
+ setAttrsForTypesSorted(false);
return T;
}
@@ -318,16 +329,16 @@ namespace {
if (A.first == AttrTy)
A.first = NewAttrTy;
}
- AttrsForTypesSorted = false;
+ setAttrsForTypesSorted(false);
}
return T;
}
/// Extract and remove the Attr* for a given attributed type.
const Attr *takeAttrForAttributedType(const AttributedType *AT) {
- if (!AttrsForTypesSorted) {
+ if (!getAttrsForTypesSorted()) {
llvm::stable_sort(AttrsForTypes, llvm::less_first());
- AttrsForTypesSorted = true;
+ setAttrsForTypesSorted(true);
}
// FIXME: This is quadratic if we have lots of reuses of the same
@@ -363,13 +374,15 @@ namespace {
LocsForMacros[MQT] = Loc;
}
- void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; }
+ void setParsedNoDeref(bool parsed) { setParsedNoDerefFlag(parsed); }
- bool didParseNoDeref() const { return parsedNoDeref; }
+ bool didParseNoDeref() const { return getParsedNoDerefFlag(); }
- void setParsedHLSLParamMod(bool Parsed) { ParsedHLSLParamMod = Parsed; }
+ void setParsedHLSLParamMod(bool Parsed) {
+ setParsedHLSLParamModFlag(Parsed);
+ }
- bool didParseHLSLParamMod() const { return ParsedHLSLParamMod; }
+ bool didParseHLSLParamMod() const { return getParsedHLSLParamModFlag(); }
~TypeProcessingState() {
if (savedAttrs.empty())
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 25e9113aeb7a4..f85f1eb1b6513 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4172,12 +4172,12 @@ class TreeTransform {
LambdaScopeInfo *LSI) {
for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
if (Expr *Init = PVD->getInit())
- LSI->ContainsUnexpandedParameterPack |=
- Init->containsUnexpandedParameterPack();
+ LSI->addUnexpandedParameterPack(
+ Init->containsUnexpandedParameterPack());
else if (PVD->hasUninstantiatedDefaultArg())
- LSI->ContainsUnexpandedParameterPack |=
+ LSI->addUnexpandedParameterPack(
PVD->getUninstantiatedDefaultArg()
- ->containsUnexpandedParameterPack();
+ ->containsUnexpandedParameterPack());
}
return getSema().BuildLambdaExpr(StartLoc, EndLoc);
}
@@ -4550,10 +4550,10 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
getSema(), EnterExpressionEvaluationContext::InitList,
Construct->isListInitialization());
- getSema().currentEvaluationContext().InLifetimeExtendingContext =
- getSema().parentEvaluationContext().InLifetimeExtendingContext;
- getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
- getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
+ getSema().currentEvaluationContext().setInLifetimeExtendingContext(
+ getSema().parentEvaluationContext().getInLifetimeExtendingContext());
+ getSema().currentEvaluationContext().setRebuildDefaultArgOrDefaultInit(
+ getSema().parentEvaluationContext().getRebuildDefaultArgOrDefaultInit());
SmallVector<Expr*, 8> NewArgs;
bool ArgChanged = false;
if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
@@ -6165,7 +6165,8 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
// If we have a VLA then it won't be a constant.
- SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
+ SemaRef.ExprEvalContexts.back().setInConditionallyConstantEvaluateContext(
+ true);
// Prefer the expression from the TypeLoc; the other may have been uniqued.
Expr *origSize = TL.getSizeExpr();
@@ -8854,19 +8855,19 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
if (LSI) {
if (auto *TD = dyn_cast<TypeDecl>(Transformed)) {
if (auto *TN = dyn_cast<TypedefNameDecl>(TD)) {
- LSI->ContainsUnexpandedParameterPack |=
- TN->getUnderlyingType()->containsUnexpandedParameterPack();
+ LSI->addUnexpandedParameterPack(
+ TN->getUnderlyingType()->containsUnexpandedParameterPack());
} else {
- LSI->ContainsUnexpandedParameterPack |=
+ LSI->addUnexpandedParameterPack(
getSema()
.getASTContext()
.getTypeDeclType(TD)
- ->containsUnexpandedParameterPack();
+ ->containsUnexpandedParameterPack());
}
}
if (auto *VD = dyn_cast<VarDecl>(Transformed))
- LSI->ContainsUnexpandedParameterPack |=
- VD->getType()->containsUnexpandedParameterPack();
+ LSI->addUnexpandedParameterPack(
+ VD->getType()->containsUnexpandedParameterPack());
}
Decls.push_back(Transformed);
@@ -9472,8 +9473,8 @@ TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
// P2718R0 - Lifetime extension in range-based for loops.
if (getSema().getLangOpts().CPlusPlus23) {
auto &LastRecord = getSema().currentEvaluationContext();
- LastRecord.InLifetimeExtendingContext = true;
- LastRecord.RebuildDefaultArgOrDefaultInit = true;
+ LastRecord.setInLifetimeExtendingContext(true);
+ LastRecord.setRebuildDefaultArgOrDefaultInit(true);
}
StmtResult Init =
S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
@@ -9605,8 +9606,8 @@ StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtPattern(
if (S->isDependent() || S->isIterating()) {
EnterExpressionEvaluationContext ExprEvalCtx(
SemaRef, SemaRef.currentEvaluationContext().Context);
- SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
- SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
+ SemaRef.currentEvaluationContext().setInLifetimeExtendingContext(true);
+ SemaRef.currentEvaluationContext().setRebuildDefaultArgOrDefaultInit(true);
if (S->isDependent()) {
// The expansion initializer should not be in the context of the expansion
@@ -9726,8 +9727,8 @@ StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtInstantiation(
{
EnterExpressionEvaluationContext ExprEvalCtx(
SemaRef, SemaRef.currentEvaluationContext().Context);
- SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
- SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
+ SemaRef.currentEvaluationContext().setInLifetimeExtendingContext(true);
+ SemaRef.currentEvaluationContext().setRebuildDefaultArgOrDefaultInit(true);
if (TransformStmts(PreambleStmts, S->getPreambleStmts()))
return StmtError();
@@ -11457,7 +11458,7 @@ OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
}
InteropInfo.Prefs.emplace_back(NewFr, std::move(NewAttrs));
}
- InteropInfo.HasPreferAttrs = C->hasPreferAttrs();
+ InteropInfo.setPreferAttrs(C->hasPreferAttrs());
return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
C->getBeginLoc(), C->getLParenLoc(),
C->getVarLoc(), C->getEndLoc());
@@ -16457,8 +16458,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
// But rule out cases e.g.
// [...C = Pack()] {}
if (NewC.EllipsisLoc.isInvalid())
- LSI->ContainsUnexpandedParameterPack |=
- Init.get()->containsUnexpandedParameterPack();
+ LSI->addUnexpandedParameterPack(
+ Init.get()->containsUnexpandedParameterPack());
}
if (Invalid)
@@ -16526,7 +16527,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
// This is not an init-capture; however it contains an unexpanded pack e.g.
// ([Pack] {}(), ...)
if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
- LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
+ LSI->addUnexpandedParameterPack(VD->isParameterPack());
// Capture the transformed variable.
getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
@@ -16542,8 +16543,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
if (TPL) {
getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
TPL);
- LSI->ContainsUnexpandedParameterPack |=
- TPL->containsUnexpandedParameterPack();
+ LSI->addUnexpandedParameterPack(TPL->containsUnexpandedParameterPack());
}
TypeLocBuilder NewCallOpTLBuilder;
@@ -16553,8 +16553,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
if (NewCallOpType.isNull())
return ExprError();
- LSI->ContainsUnexpandedParameterPack |=
- NewCallOpType->containsUnexpandedParameterPack();
+ LSI->addUnexpandedParameterPack(
+ NewCallOpType->containsUnexpandedParameterPack());
TypeSourceInfo *NewCallOpTSI =
NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
@@ -16572,7 +16572,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
TRC.ConstraintExpr = E.get();
}
- LSI->BeforeCompoundStatement = false;
+ LSI->setBeforeCompoundStatement(false);
getSema().CompleteLambdaCallOperator(
NewCallOperator, E->getCallOperator()->getLocation(),
E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
@@ -17978,7 +17978,7 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
blockScope->TheDecl->setParams(params);
if (!oldBlock->blockMissingReturnType()) {
- blockScope->HasImplicitReturnType = false;
+ blockScope->setHasImplicitReturnType(false);
blockScope->ReturnType = exprResultType;
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index e6f6be496e5e5..32c0bc7f8eead 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -753,8 +753,8 @@ bool PCHValidator::ReadDiagnosticOptions(DiagnosticOptions &DiagOpts,
// FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
// contains the union of their flags.
return checkDiagnosticMappings(*Diags, ExistingDiags, ModuleFilename,
- TopM->IsSystem, SystemHeaderWarningsInModule,
- Complain);
+ TopM->getIsSystem(),
+ SystemHeaderWarningsInModule, Complain);
}
/// Collect the macro definitions provided by the given preprocessor
@@ -1077,7 +1077,7 @@ readULEBKeyDataLength(const unsigned char *&P) {
void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener,
bool TakeOwnership) {
DeserializationListener = Listener;
- OwnsDeserializationListener = TakeOwnership;
+ setOwnsDeserializationListener(TakeOwnership);
}
unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) {
@@ -2378,9 +2378,9 @@ unsigned HeaderFileInfoTrait::ComputeHash(internal_key_ref ikey) {
HeaderFileInfoTrait::internal_key_type
HeaderFileInfoTrait::GetInternalKey(external_key_type ekey) {
- internal_key_type ikey = {ekey.getSize(),
- M.HasTimestamps ? ekey.getModificationTime() : 0,
- ekey.getName(), /*Imported*/ false};
+ internal_key_type ikey = {
+ ekey.getSize(), M.getHasTimestamps() ? ekey.getModificationTime() : 0,
+ ekey.getName(), /*Imported*/ false};
return ikey;
}
@@ -2900,14 +2900,14 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
uint64_t StoredContentHash = FI.ContentHash;
// For standard C++ modules, we don't need to check the inputs.
- bool SkipChecks = F.StandardCXXModule;
+ bool SkipChecks = F.getStandardCXXModule();
const HeaderSearchOptions &HSOpts =
PP.getHeaderSearchInfo().getHeaderSearchOpts();
// The option ForceCheckCXX20ModulesInputFiles is only meaningful for C++20
// modules.
- if (F.StandardCXXModule && HSOpts.ForceCheckCXX20ModulesInputFiles) {
+ if (F.getStandardCXXModule() && HSOpts.ForceCheckCXX20ModulesInputFiles) {
SkipChecks = false;
Overridden = false;
}
@@ -2954,7 +2954,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
}
auto HasInputContentChanged = [&](Change OriginalChange) {
- assert(ValidateASTInputFilesContent &&
+ assert(getValidateASTInputFilesContent() &&
"We should only check the content of the inputs with "
"ValidateASTInputFilesContent enabled.");
@@ -2988,7 +2988,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
// In case the modification time changes but not the content,
// accept the cached file as legit.
- if (ValidateASTInputFilesContent)
+ if (getValidateASTInputFilesContent())
return HasInputContentChanged(MTimeChange);
return MTimeChange;
@@ -3001,15 +3001,16 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
// When ForceCheckCXX20ModulesInputFiles and ValidateASTInputFilesContent
// enabled, it is better to check the contents of the inputs. Since we can't
// get correct modified time information for inputs from overriden inputs.
- if (HSOpts.ForceCheckCXX20ModulesInputFiles && ValidateASTInputFilesContent &&
- F.StandardCXXModule && FileChange.Kind == Change::None)
+ if (HSOpts.ForceCheckCXX20ModulesInputFiles &&
+ getValidateASTInputFilesContent() && F.getStandardCXXModule() &&
+ FileChange.Kind == Change::None)
FileChange = HasInputContentChanged(FileChange);
// When we have StoredTime equal to zero and ValidateASTInputFilesContent,
// it is better to check the content of the input files because we cannot rely
// on the file modification time, which will be the same (zero) for these
// files.
- if (!StoredTime && ValidateASTInputFilesContent &&
+ if (!StoredTime && getValidateASTInputFilesContent() &&
FileChange.Kind == Change::None)
FileChange = HasInputContentChanged(FileChange);
@@ -3339,15 +3340,15 @@ ASTReader::ReadControlBlock(ModuleFile &F,
// so we verify all input files. Otherwise, verify only user input
// files.
- unsigned N = ValidateSystemInputs ? NumInputs : NumUserInputs;
- F.InputFilesValidationStatus = ValidateSystemInputs
+ unsigned N = getValidateSystemInputs() ? NumInputs : NumUserInputs;
+ F.InputFilesValidationStatus = getValidateSystemInputs()
? InputFilesValidation::AllFiles
: InputFilesValidation::UserFiles;
auto [_, WasValidated] = wasValidatedInBuildSession(F, HSOpts);
if (WasValidated) {
- N = ForceValidateUserInputs ? NumUserInputs : 0;
+ N = getForceValidateUserInputs() ? NumUserInputs : 0;
F.InputFilesValidationStatus =
- ForceValidateUserInputs
+ getForceValidateUserInputs()
? InputFilesValidation::UserFiles
: InputFilesValidation::SkippedInBuildSession;
}
@@ -3429,8 +3430,8 @@ ASTReader::ReadControlBlock(ModuleFile &F,
return Result;
}
- if (DisableValidation ||
- (AllowConfigurationMismatch && Result == ConfigurationMismatch))
+ if (DisableValidation || (getAllowConfigurationMismatch() &&
+ Result == ConfigurationMismatch))
Result = Success;
// If we can't load the module, exit early since we likely
@@ -3484,7 +3485,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
canRecoverFromOutOfDate(F.FileName, ClientLoadCapabilities))
return OutOfDate;
- if (!AllowASTWithCompilerErrors) {
+ if (!getAllowASTWithCompilerErrors()) {
Diag(diag::err_ast_file_with_compiler_errors)
<< moduleKindForDiagnostic(F.Kind) << F.FileName;
return HadErrors;
@@ -3496,14 +3497,14 @@ ASTReader::ReadControlBlock(ModuleFile &F,
Diags.UnrecoverableErrorOccurred = true;
}
- F.RelocatablePCH = Record[4];
+ F.setRelocatablePCH(Record[4]);
// Relative paths in a relocatable PCH are relative to our sysroot.
- if (F.RelocatablePCH)
+ if (F.getRelocatablePCH())
F.BaseDirectory = isysroot.empty() ? "/" : isysroot;
- F.StandardCXXModule = Record[5];
+ F.setStandardCXXModule(Record[5]);
- F.HasTimestamps = Record[6];
+ F.setHasTimestamps(Record[6]);
const std::string &CurBranch = getClangFullRepositoryVersion();
StringRef ASTBranch = Blob;
@@ -4340,7 +4341,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
// For standard C++20 module, we will only reads the instantiations
// if it is the main file.
- if (!F.StandardCXXModule || F.Kind == MK_MainFile) {
+ if (!F.getStandardCXXModule() || F.Kind == MK_MainFile) {
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
PendingInstantiations.push_back(
{ReadDeclID(F, Record, I),
@@ -5054,12 +5055,12 @@ bool ASTReader::loadGlobalIndex() {
if (GlobalIndex)
return false;
- if (TriedLoadingGlobalIndex || !UseGlobalIndex ||
+ if (getTriedLoadingGlobalIndex() || !getUseGlobalIndex() ||
!PP.getLangOpts().Modules)
return true;
// Try to load the global index.
- TriedLoadingGlobalIndex = true;
+ setTriedLoadingGlobalIndex(true);
StringRef SpecificModuleCachePath =
getPreprocessor().getHeaderSearchInfo().getSpecificModuleCachePath();
std::pair<GlobalModuleIndex *, llvm::Error> Result =
@@ -5076,8 +5077,8 @@ bool ASTReader::loadGlobalIndex() {
}
bool ASTReader::isGlobalIndexUnavailable() const {
- return PP.getLangOpts().Modules && UseGlobalIndex &&
- !hasGlobalIndex() && TriedLoadingGlobalIndex;
+ return PP.getLangOpts().Modules && getUseGlobalIndex() && !hasGlobalIndex() &&
+ getTriedLoadingGlobalIndex();
}
/// Given a cursor at the start of an AST file, scan ahead and drop the
@@ -5185,7 +5186,7 @@ ASTReader::ASTReadResult ASTReader::ReadAST(ModuleFileName FileName,
}
// The AST block should always have a definition for the main module.
- if (F.isModule() && !F.DidReadTopLevelSubmodule) {
+ if (F.isModule() && !F.getDidReadTopLevelSubmodule()) {
Error(diag::err_module_file_missing_top_level_submodule, F.FileName);
return Failure;
}
@@ -5543,7 +5544,7 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
// If F was directly imported by another module, it's implicitly validated by
// the importing module.
if (DisableValidation || WasImportedBy ||
- (AllowConfigurationMismatch && Result == ConfigurationMismatch))
+ (getAllowConfigurationMismatch() && Result == ConfigurationMismatch))
return Success;
if (Result == Failure) {
@@ -6578,7 +6579,7 @@ Module *ASTReader::getSubmodule(uint32_t GlobalID) {
}
}
- F.DidReadTopLevelSubmodule = true;
+ F.setDidReadTopLevelSubmodule(true);
CurrentModule->setASTFileNameAndKey(F.FileName, F.FileKey);
CurrentModule->PresumedModuleMapFile = F.ModuleMapPath;
}
@@ -6592,17 +6593,17 @@ Module *ASTReader::getSubmodule(uint32_t GlobalID) {
// duplicate locations for the same module map file.
CurrentModule->DefinitionLoc = DefinitionLoc;
CurrentModule->Signature = F.Signature;
- CurrentModule->IsFromModuleFile = true;
+ CurrentModule->setIsFromModuleFile(true);
if (InferredAllowedBy.isValid())
ModMap.setInferredModuleAllowedBy(CurrentModule, InferredAllowedBy);
- CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
- CurrentModule->IsExternC = IsExternC;
- CurrentModule->InferSubmodules = InferSubmodules;
- CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
- CurrentModule->InferExportWildcard = InferExportWildcard;
- CurrentModule->ConfigMacrosExhaustive = ConfigMacrosExhaustive;
- CurrentModule->ModuleMapIsPrivate = ModuleMapIsPrivate;
- CurrentModule->NamedModuleHasInit = NamedModuleHasInit;
+ CurrentModule->setIsSystem(IsSystem || CurrentModule->getIsSystem());
+ CurrentModule->setIsExternC(IsExternC);
+ CurrentModule->setInferSubmodules(InferSubmodules);
+ CurrentModule->setInferExplicitSubmodules(InferExplicitSubmodules);
+ CurrentModule->setInferExportWildcard(InferExportWildcard);
+ CurrentModule->setConfigMacrosExhaustive(ConfigMacrosExhaustive);
+ CurrentModule->setModuleMapIsPrivate(ModuleMapIsPrivate);
+ CurrentModule->setNamedModuleHasInit(NamedModuleHasInit);
if (!ParentModule && !F.BaseDirectory.empty()) {
if (auto Dir = FileMgr.getOptionalDirectoryRef(F.BaseDirectory))
@@ -6630,9 +6631,9 @@ Module *ASTReader::getSubmodule(uint32_t GlobalID) {
// imported module file.
CurrentModule->Requirements.clear();
CurrentModule->MissingHeaders.clear();
- CurrentModule->IsUnimportable =
- ParentModule && ParentModule->IsUnimportable;
- CurrentModule->IsAvailable = !CurrentModule->IsUnimportable;
+ CurrentModule->setIsUnimportable(ParentModule &&
+ ParentModule->getIsUnimportable());
+ CurrentModule->setIsAvailable(!CurrentModule->getIsUnimportable());
break;
}
@@ -6742,7 +6743,7 @@ Module *ASTReader::getSubmodule(uint32_t GlobalID) {
if (!ContextObj)
break;
// Standard C++ module has its own way to initialize variables.
- if (!F.StandardCXXModule || F.Kind == MK_MainFile) {
+ if (!F.getStandardCXXModule() || F.Kind == MK_MainFile) {
SmallVector<GlobalDeclID, 16> Inits;
for (unsigned I = 0; I < Record.size(); /*in loop*/)
Inits.push_back(ReadDeclID(F, Record, I));
@@ -11479,8 +11480,13 @@ void ASTReader::FinishedDeserializing() {
{
// Guard variable to avoid recursively entering the process of passing
// decls to consumer.
- SaveAndRestore GuardPassingDeclsToConsumer(CanPassDeclsToConsumer,
- /*NewValue=*/false);
+ auto GuardPassingDeclsToConsumer = [PackedFlagOwner = this] {
+ const bool PackedFlagOld = PackedFlagOwner->getCanPassDeclsToConsumer();
+ PackedFlagOwner->setCanPassDeclsToConsumer(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setCanPassDeclsToConsumer(PackedFlagOld);
+ });
+ }();
// Propagate exception specification and deduced type updates along
// redeclaration chains.
@@ -11580,12 +11586,15 @@ ASTReader::ASTReader(Preprocessor &PP, ModuleCache &ModCache,
PP.getHeaderSearchInfo()),
DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
DisableValidationKind(DisableValidationKind),
- AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
- AllowConfigurationMismatch(AllowConfigurationMismatch),
- ValidateSystemInputs(ValidateSystemInputs),
- ForceValidateUserInputs(ForceValidateUserInputs),
- ValidateASTInputFilesContent(ValidateASTInputFilesContent),
- UseGlobalIndex(UseGlobalIndex), CurrSwitchCaseStmts(&SwitchCaseStmts) {
+ CurrSwitchCaseStmts(&SwitchCaseStmts),
+ PreloadedDeclIDs(decltype(this->PreloadedDeclIDs)::withFlags(
+ unsigned(ForceValidateUserInputs) |
+ (unsigned(ValidateASTInputFilesContent) << 1) |
+ (unsigned(UseGlobalIndex) << 2))),
+ CommentsCursors(decltype(this->CommentsCursors)::withFlags(
+ (unsigned(AllowASTWithCompilerErrors) << 1) |
+ (unsigned(AllowConfigurationMismatch) << 2) |
+ (unsigned(ValidateSystemInputs) << 3))) {
SourceMgr.setExternalSLocEntrySource(this);
PathBuf.reserve(256);
@@ -11604,7 +11613,7 @@ ASTReader::ASTReader(Preprocessor &PP, ModuleCache &ModCache,
}
ASTReader::~ASTReader() {
- if (OwnsDeserializationListener)
+ if (getOwnsDeserializationListener())
delete DeserializationListener;
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index d7d650ef02192..c8b38f7c48bc2 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -57,6 +57,7 @@
#include "clang/Serialization/ModuleFile.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
@@ -67,6 +68,7 @@
#include <cassert>
#include <cstdint>
#include <cstring>
+#include <memory>
#include <string>
#include <utility>
@@ -4449,13 +4451,18 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
void ASTReader::PassInterestingDeclsToConsumer() {
assert(Consumer);
- if (!CanPassDeclsToConsumer)
+ if (!getCanPassDeclsToConsumer())
return;
// Guard variable to avoid recursively redoing the process of passing
// decls to consumer.
- SaveAndRestore GuardPassingDeclsToConsumer(CanPassDeclsToConsumer,
- /*NewValue=*/false);
+ auto GuardPassingDeclsToConsumer = [PackedFlagOwner = this] {
+ const bool PackedFlagOld = PackedFlagOwner->getCanPassDeclsToConsumer();
+ PackedFlagOwner->setCanPassDeclsToConsumer(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setCanPassDeclsToConsumer(PackedFlagOld);
+ });
+ }();
// Ensure that we've loaded all potentially-interesting declarations
// that need to be eagerly loaded.
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 26aee27c65e82..9217cca0635bc 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -837,10 +837,10 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
static ConstraintSatisfaction
readConstraintSatisfaction(ASTRecordReader &Record) {
ConstraintSatisfaction Satisfaction;
- Satisfaction.IsSatisfied = Record.readInt();
- Satisfaction.ContainsErrors = Record.readInt();
+ Satisfaction.setIsSatisfied(Record.readInt());
+ Satisfaction.setContainsErrors(Record.readInt());
const ASTContext &C = Record.getContext();
- if (!Satisfaction.IsSatisfied) {
+ if (!Satisfaction.isSatisfied()) {
unsigned NumDetailRecords = Record.readInt();
for (unsigned i = 0; i != NumDetailRecords; ++i) {
auto Kind = Record.readInt();
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 0afba1c84fd62..da9ef3b84cb33 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -94,6 +94,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitstream/BitCodes.h"
#include "llvm/Bitstream/BitstreamWriter.h"
@@ -1479,8 +1480,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
CLANG_VERSION_MINOR,
!isysroot.empty(),
isWritingStdCXXNamedModules(),
- IncludeTimestamps,
- ASTHasCompilerErrors};
+ getIncludeTimestamps(),
+ getASTHasCompilerErrors()};
Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,
getClangFullRepositoryVersion());
}
@@ -1605,11 +1606,11 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
Record.push_back((unsigned)M.Kind); // FIXME: Stable encoding
AddSourceLocation(M.ImportLoc, Record);
AddStringBlob(M.ModuleName, Record, Blob);
- Record.push_back(M.StandardCXXModule);
+ Record.push_back(M.getStandardCXXModule());
// We don't want to hard code the information about imported modules
// in the C++20 named modules.
- if (M.StandardCXXModule) {
+ if (M.getStandardCXXModule()) {
Record.push_back(0);
Record.push_back(0);
Record.push_back(0);
@@ -1744,7 +1745,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
// If we're building an implicit module with a context hash, the importer is
// guaranteed to have the same macros defined on the command line. Skip
// writing them.
- bool SkipMacros = BuildingImplicitModule && !HSOpts.DisableModuleHash;
+ bool SkipMacros = getBuildingImplicitModule() && !HSOpts.DisableModuleHash;
bool WriteMacros = !SkipMacros;
Record.push_back(WriteMacros);
if (WriteMacros) {
@@ -2127,12 +2128,14 @@ namespace {
data_type(const HeaderFileInfo &HFI, bool AlreadyIncluded,
ArrayRef<ModuleMap::KnownHeader> KnownHeaders,
UnresolvedModule Unresolved)
- : HFI(HFI), AlreadyIncluded(AlreadyIncluded),
- KnownHeaders(KnownHeaders), Unresolved(Unresolved) {}
+ : HFI(HFI), KnownHeaders(decltype(this->KnownHeaders)::withFlags(
+ unsigned(AlreadyIncluded), KnownHeaders)),
+ Unresolved(Unresolved) {}
HeaderFileInfo HFI;
- bool AlreadyIncluded;
- SmallVector<ModuleMap::KnownHeader, 1> KnownHeaders;
+ bool getAlreadyIncluded() const { return KnownHeaders.getFlag(0); }
+ void setAlreadyIncluded(bool Value) { KnownHeaders.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<ModuleMap::KnownHeader, 1> KnownHeaders;
UnresolvedModule Unresolved;
};
using data_type_ref = const data_type &;
@@ -2180,11 +2183,11 @@ namespace {
endian::Writer LE(Out, llvm::endianness::little);
uint64_t Start = Out.tell(); (void)Start;
- unsigned char Flags = (Data.AlreadyIncluded << 6)
- | (Data.HFI.isImport << 5)
- | (Writer.isWritingStdCXXNamedModules() ? 0 :
- Data.HFI.isPragmaOnce << 4)
- | (Data.HFI.DirInfo << 1);
+ unsigned char Flags =
+ (Data.getAlreadyIncluded() << 6) | (Data.HFI.isImport << 5) |
+ (Writer.isWritingStdCXXNamedModules() ? 0
+ : Data.HFI.isPragmaOnce << 4) |
+ (Data.HFI.DirInfo << 1);
LE.write<uint8_t>(Flags);
if (Data.HFI.LazyControllingMacro.isID())
@@ -2246,7 +2249,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
for (const auto &U : M->MissingHeaders) {
// Check that we were given enough information to build a module
// without this file existing on disk.
- if (!U.Size || (!U.ModTime && IncludeTimestamps)) {
+ if (!U.Size || (!U.ModTime && getIncludeTimestamps())) {
PP->Diag(U.FileNameLoc, diag::err_module_no_size_mtime_for_header)
<< WritingModule->getFullModuleName() << U.Size.has_value()
<< U.FileName;
@@ -2262,7 +2265,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
SavedStrings.push_back(FilenameDup.data());
HeaderFileInfoTrait::key_type Key = {
- FilenameDup, *U.Size, IncludeTimestamps ? *U.ModTime : 0};
+ FilenameDup, *U.Size, getIncludeTimestamps() ? *U.ModTime : 0};
HeaderFileInfoTrait::data_type Data = {
Empty, false, {}, {M, ModuleMap::headerKindToRole(U.Kind)}};
// FIXME: Deal with cases where there are multiple unresolved header
@@ -3141,7 +3144,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule, ASTContext *Context) {
ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
FileID UnadjustedInferredFID;
- if (Mod->IsInferred)
+ if (Mod->getIsInferred())
UnadjustedInferredFID = ModMap.getModuleMapFileIDForUniquing(Mod);
int InferredFID = getAdjustedFileID(UnadjustedInferredFID).getOpaqueValue();
@@ -3153,16 +3156,16 @@ void ASTWriter::WriteSubmodules(Module *WritingModule, ASTContext *Context) {
(RecordData::value_type)Mod->Kind,
DefinitionLoc,
(RecordData::value_type)InferredFID,
- Mod->IsFramework,
- Mod->IsExplicit,
- Mod->IsSystem,
- Mod->IsExternC,
- Mod->InferSubmodules,
- Mod->InferExplicitSubmodules,
- Mod->InferExportWildcard,
- Mod->ConfigMacrosExhaustive,
- Mod->ModuleMapIsPrivate,
- Mod->NamedModuleHasInit};
+ Mod->getIsFramework(),
+ Mod->getIsExplicit(),
+ Mod->getIsSystem(),
+ Mod->getIsExternC(),
+ Mod->getInferSubmodules(),
+ Mod->getInferExplicitSubmodules(),
+ Mod->getInferExportWildcard(),
+ Mod->getConfigMacrosExhaustive(),
+ Mod->getModuleMapIsPrivate(),
+ Mod->getNamedModuleHasInit()};
Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name);
}
@@ -3272,7 +3275,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule, ASTContext *Context) {
// Emit the reachable initializers.
// The initializer may only be unreachable in reduced BMI.
- if (Context && !GeneratingReducedBMI) {
+ if (Context && !getGeneratingReducedBMI()) {
RecordData Inits;
for (Decl *D : Context->getModuleInitializers(Mod))
if (wasDeclEmitted(D))
@@ -3495,13 +3498,13 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
return 0;
// In reduced BMI, we don't care the declarations in functions.
- if (GeneratingReducedBMI && DC->isFunctionOrMethod())
+ if (getGeneratingReducedBMI() && DC->isFunctionOrMethod())
return 0;
uint64_t Offset = Stream.GetCurrentBitNo();
SmallVector<DeclID, 128> KindDeclPairs;
for (const auto *D : DC->decls()) {
- if (DoneWritingDeclsAndTypes && !wasDeclEmitted(D))
+ if (getDoneWritingDeclsAndTypesFlag() && !wasDeclEmitted(D))
continue;
// We don't need to write decls with internal linkage into reduced BMI.
@@ -3509,7 +3512,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
// the program illegal. However, there are too many use of static inline
// functions in the global module fragment and it will be breaking change
// to forbid that. So we have to allow to emit such declarations from GMF.
- if (GeneratingReducedBMI && !D->isFromExplicitGlobalModule() &&
+ if (getGeneratingReducedBMI() && !D->isFromExplicitGlobalModule() &&
IsInternalDeclFromFileContext(D))
continue;
@@ -4779,7 +4782,8 @@ void ASTWriter::GenerateNameLookupTable(
// Also in reduced BMI, we'd like to avoid writing unreachable
// declarations in GMF, so we need to avoid writing declarations
// that entirely external or unreachable.
- if (GeneratingReducedBMI && isLookupResultNotInteresting(*this, Result))
+ if (getGeneratingReducedBMI() &&
+ isLookupResultNotInteresting(*this, Result))
continue;
// We also skip empty results. If any of the results could be external and
// the currently available results are empty, then all of the results are
@@ -5004,12 +5008,12 @@ void ASTWriter::WriteDeclContextVisibleBlock(
if (ND->isFromASTFile())
continue;
- if (DoneWritingDeclsAndTypes && !wasDeclEmitted(ND))
+ if (getDoneWritingDeclsAndTypesFlag() && !wasDeclEmitted(ND))
continue;
// We don't need to force emitting internal decls into reduced BMI.
// See comments in ASTWriter::WriteDeclContextLexicalBlock for details.
- if (GeneratingReducedBMI && !ND->isFromExplicitGlobalModule() &&
+ if (getGeneratingReducedBMI() && !ND->isFromExplicitGlobalModule() &&
IsInternalDeclFromFileContext(ND))
continue;
@@ -5242,7 +5246,7 @@ void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) {
/// Write the state of 'pragma ms_struct' at the end of the module.
void ASTWriter::WriteMSStructPragmaOptions(Sema &SemaRef) {
RecordData Record;
- Record.push_back(SemaRef.MSStructPragmaOn ? PMSST_ON : PMSST_OFF);
+ Record.push_back(SemaRef.getMSStructPragmaOn() ? PMSST_ON : PMSST_OFF);
Stream.EmitRecord(MSSTRUCT_PRAGMA_OPTIONS, Record);
}
@@ -5457,7 +5461,8 @@ void ASTWriter::AddStringBlob(StringRef Str, RecordDataImpl &Record,
}
bool ASTWriter::PreparePathForOutput(SmallVectorImpl<char> &Path) {
- assert(WritingAST && "can't prepare path for output when not writing AST");
+ assert(getWritingAST() &&
+ "can't prepare path for output when not writing AST");
// Leave special file names as they are.
StringRef PathStr(Path.data(), Path.size());
@@ -5541,9 +5546,12 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
bool IncludeTimestamps, bool BuildingImplicitModule,
bool GeneratingReducedBMI)
: Stream(Stream), Buffer(Buffer), ModCache(ModCache),
- CodeGenOpts(CodeGenOpts), IncludeTimestamps(IncludeTimestamps),
- BuildingImplicitModule(BuildingImplicitModule),
- GeneratingReducedBMI(GeneratingReducedBMI) {
+ CodeGenOpts(CodeGenOpts),
+ Redeclarations(decltype(this->Redeclarations)::withFlags(
+ (unsigned(GeneratingReducedBMI) << 1))),
+ PendingEmittingVTables(decltype(this->PendingEmittingVTables)::withFlags(
+ unsigned(IncludeTimestamps) |
+ (unsigned(BuildingImplicitModule) << 1))) {
for (const auto &Ext : Extensions) {
if (auto Writer = Ext->createExtensionWriter(*this))
ModuleFileExtensionWriters.push_back(std::move(Writer));
@@ -5553,12 +5561,12 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
ASTWriter::~ASTWriter() = default;
const LangOptions &ASTWriter::getLangOpts() const {
- assert(WritingAST && "can't determine lang opts when not writing AST");
+ assert(getWritingAST() && "can't determine lang opts when not writing AST");
return PP->getLangOpts();
}
time_t ASTWriter::getTimestampForOutput(time_t ModTime) const {
- return IncludeTimestamps ? ModTime : 0;
+ return getIncludeTimestamps() ? ModTime : 0;
}
ASTFileSignature
@@ -5566,13 +5574,14 @@ ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
StringRef OutputFile, Module *WritingModule,
StringRef isysroot) {
llvm::TimeTraceScope scope("WriteAST", OutputFile);
- WritingAST = true;
+ setWritingAST(true);
Sema *SemaPtr = dyn_cast<Sema *>(Subject);
Preprocessor &PPRef =
SemaPtr ? SemaPtr->getPreprocessor() : *cast<Preprocessor *>(Subject);
- ASTHasCompilerErrors = PPRef.getDiagnostics().hasUncompilableErrorOccurred();
+ setASTHasCompilerErrors(
+ PPRef.getDiagnostics().hasUncompilableErrorOccurred());
// Emit the file header.
Stream.Emit((unsigned)'C', 8);
@@ -5589,7 +5598,7 @@ ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
this->WritingModule = nullptr;
this->BaseDirectory.clear();
- WritingAST = false;
+ setWritingAST(false);
return Signature;
}
@@ -5710,7 +5719,7 @@ void ASTWriter::computeNonAffectingInputFiles() {
void ASTWriter::prepareLazyUpdates() {
// In C++20 named modules with reduced BMI, we only apply the update
// if these updates are touched.
- if (!GeneratingReducedBMI)
+ if (!getGeneratingReducedBMI())
return;
DeclUpdateMap DeclUpdatesTmp;
@@ -5796,7 +5805,7 @@ void ASTWriter::PrepareWritingSpecialDecls(Sema &SemaRef) {
if (D->isFromASTFile())
continue;
- if (GeneratingReducedBMI) {
+ if (getGeneratingReducedBMI()) {
if (D->isFromExplicitGlobalModule())
continue;
@@ -5822,7 +5831,7 @@ void ASTWriter::PrepareWritingSpecialDecls(Sema &SemaRef) {
GetDeclRef(D);
}
- if (GeneratingReducedBMI)
+ if (getGeneratingReducedBMI())
return;
// Writing all of the tentative definitions in this file, in
@@ -5989,7 +5998,7 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
UnusedLocalTypedefNameCandidates);
- if (!GeneratingReducedBMI) {
+ if (!getGeneratingReducedBMI()) {
// Write the record containing pending implicit instantiations.
RecordData PendingInstantiations;
for (const auto &I : SemaRef.PendingInstantiations) {
@@ -6461,11 +6470,11 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
}
} while (!DeclUpdates.empty());
- DoneWritingDeclsAndTypes = true;
+ setDoneWritingDeclsAndTypesFlag(true);
// DelayedNamespace is only meaningful in reduced BMI.
// See the comments of DelayedNamespace for details.
- assert(DelayedNamespace.empty() || GeneratingReducedBMI);
+ assert(DelayedNamespace.empty() || getGeneratingReducedBMI());
RecordData DelayedNamespaceRecord;
for (NamespaceDecl *NS : DelayedNamespace) {
LookupBlockOffsets Offsets;
@@ -6789,7 +6798,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(ASTContext &Context,
// Add a trailing update record, if any. These must go last because we
// lazily load their attached statement.
- if (!GeneratingReducedBMI || !CanElideDeclDef(D)) {
+ if (!getGeneratingReducedBMI() || !CanElideDeclDef(D)) {
if (HasUpdatedBody) {
const auto *Def = cast<FunctionDecl>(D);
Record.push_back(
@@ -7113,7 +7122,7 @@ TypeID ASTWriter::GetOrCreateTypeID(ASTContext &Context, QualType T) {
TypeIdx &Idx = TypeIdxs[T];
if (Idx.getValue() == 0) {
- if (DoneWritingDeclsAndTypes) {
+ if (getDoneWritingDeclsAndTypesFlag()) {
assert(0 && "New type seen after serializing all the types to emit!");
return TypeIdx();
}
@@ -7167,7 +7176,8 @@ void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
}
LocalDeclID ASTWriter::GetDeclRef(const Decl *D) {
- assert(WritingAST && "Cannot request a declaration ID before AST writing");
+ assert(getWritingAST() &&
+ "Cannot request a declaration ID before AST writing");
if (!D) {
return LocalDeclID();
@@ -7187,7 +7197,7 @@ LocalDeclID ASTWriter::GetDeclRef(const Decl *D) {
assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
LocalDeclID &ID = DeclIDs[D];
if (ID.isInvalid()) {
- if (DoneWritingDeclsAndTypes) {
+ if (getDoneWritingDeclsAndTypesFlag()) {
assert(0 && "New decl seen after serializing all the decls to emit!");
return LocalDeclID();
}
@@ -7217,7 +7227,7 @@ LocalDeclID ASTWriter::getDeclID(const Decl *D) {
bool ASTWriter::wasDeclEmitted(const Decl *D) const {
assert(D);
- assert(DoneWritingDeclsAndTypes &&
+ assert(getDoneWritingDeclsAndTypesFlag() &&
"wasDeclEmitted should only be called after writing declarations");
if (D->isFromASTFile())
@@ -7225,13 +7235,13 @@ bool ASTWriter::wasDeclEmitted(const Decl *D) const {
bool Emitted = DeclIDs.contains(D);
assert((Emitted || (!D->getOwningModule() && isWritingStdCXXNamedModules()) ||
- GeneratingReducedBMI) &&
+ getGeneratingReducedBMI()) &&
"The declaration within modules can only be omitted in reduced BMI.");
return Emitted;
}
void ASTWriter::getLazyUpdates(const Decl *D) {
- if (!GeneratingReducedBMI)
+ if (!getGeneratingReducedBMI())
return;
if (auto *Iter = DeclUpdatesLazy.find(D); Iter != DeclUpdatesLazy.end()) {
@@ -7742,7 +7752,7 @@ void ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) {
void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(D->isCompleteDefinition());
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (auto *RD = dyn_cast<CXXRecordDecl>(D)) {
// We are interested when a PCH decl is modified.
if (RD->isFromASTFile()) {
@@ -7790,7 +7800,7 @@ void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
assert(DC == DC->getPrimaryContext() && "added to non-primary context");
assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (UpdatedDeclContexts.insert(DC) && !cast<Decl>(DC)->isFromASTFile()) {
// We're adding a visible declaration to a predefined decl context. Ensure
// that we write out all of its lookup results so we don't get a nasty
@@ -7814,14 +7824,14 @@ void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
// A decl coming from PCH was modified.
assert(RD->isCompleteDefinition());
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
DeclUpdates[RD].push_back(
DeclUpdate(DeclUpdateKind::CXXAddedImplicitMember, D));
}
void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!DoneWritingDeclsAndTypes && "Already done writing updates!");
+ assert(!getDoneWritingDeclsAndTypesFlag() && "Already done writing updates!");
if (!Chain) return;
Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
// If we don't already know the exception specification for this redecl
@@ -7836,7 +7846,7 @@ void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!Chain) return;
Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
DeclUpdates[D].push_back(
@@ -7848,7 +7858,7 @@ void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
const FunctionDecl *Delete,
Expr *ThisArg) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
assert(Delete && "Not given an operator delete");
if (!Chain) return;
Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
@@ -7861,7 +7871,7 @@ void ASTWriter::ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
const FunctionDecl *GlobDelete) {
if (Chain && Chain->isProcessingUpdateRecords())
return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
assert(GlobDelete && "Not given an operator delete");
if (!Chain)
return;
@@ -7875,7 +7885,7 @@ void ASTWriter::ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
const FunctionDecl *ArrayDelete) {
if (Chain && Chain->isProcessingUpdateRecords())
return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
assert(ArrayDelete && "Not given an operator delete");
if (!Chain)
return;
@@ -7889,7 +7899,7 @@ void ASTWriter::ResolvedOperatorGlobArrayDelete(
const CXXDestructorDecl *DD, const FunctionDecl *GlobArrayDelete) {
if (Chain && Chain->isProcessingUpdateRecords())
return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
assert(GlobArrayDelete && "Not given an operator delete");
if (!Chain)
return;
@@ -7901,7 +7911,7 @@ void ASTWriter::ResolvedOperatorGlobArrayDelete(
void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return; // Declaration not imported from PCH.
@@ -7916,7 +7926,7 @@ void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -7925,7 +7935,7 @@ void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) {
void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -7939,7 +7949,7 @@ void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
void ASTWriter::InstantiationRequested(const ValueDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -7956,7 +7966,7 @@ void ASTWriter::InstantiationRequested(const ValueDecl *D) {
void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -7965,7 +7975,7 @@ void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
}
void ASTWriter::DefaultMemberInitializerInstantiated(const FieldDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -7976,7 +7986,7 @@ void ASTWriter::DefaultMemberInitializerInstantiated(const FieldDecl *D) {
void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!IFD->isFromASTFile())
return; // Declaration not imported from PCH.
@@ -7987,7 +7997,7 @@ void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
// If there is *any* declaration of the entity that's not from an AST file,
// we can skip writing the update record. We make sure that isUsed() triggers
@@ -8001,7 +8011,7 @@ void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -8011,7 +8021,7 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -8022,7 +8032,7 @@ void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {
void ASTWriter::DeclarationMarkedOpenMPIndirectCall(const Decl *D) {
if (Chain && Chain->isProcessingUpdateRecords())
return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -8033,7 +8043,7 @@ void ASTWriter::DeclarationMarkedOpenMPIndirectCall(const Decl *D) {
void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
const Attr *Attr) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!D->isFromASTFile())
return;
@@ -8043,7 +8053,7 @@ void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
assert(!D->isUnconditionallyVisible() && "expected a hidden declaration");
DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::DeclExported, M));
}
@@ -8051,7 +8061,7 @@ void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
void ASTWriter::AddedAttributeToRecord(const Attr *Attr,
const RecordDecl *Record) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!Record->isFromASTFile())
return;
DeclUpdates[Record].push_back(
@@ -8060,7 +8070,7 @@ void ASTWriter::AddedAttributeToRecord(const Attr *Attr,
void ASTWriter::AddedCXXTemplateSpecialization(
const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!TD->getFirstDecl()->isFromASTFile())
return;
@@ -8072,7 +8082,7 @@ void ASTWriter::AddedCXXTemplateSpecialization(
void ASTWriter::AddedCXXTemplateSpecialization(
const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!TD->getFirstDecl()->isFromASTFile())
return;
@@ -8084,7 +8094,7 @@ void ASTWriter::AddedCXXTemplateSpecialization(
void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {
- assert(!WritingAST && "Already writing the AST!");
+ assert(!getWritingAST() && "Already writing the AST!");
if (!TD->getFirstDecl()->isFromASTFile())
return;
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 2f5b9ed925097..9e2082c03f3fa 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -3118,7 +3118,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
assert(ID >= FirstDeclID && "invalid decl ID");
RecordData Record;
- ASTDeclWriter W(*this, Context, Record, GeneratingReducedBMI);
+ ASTDeclWriter W(*this, Context, Record, getGeneratingReducedBMI());
// Build a record for this declaration
W.Visit(D);
diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp
index 8bc7e1782c2d9..99d168451ec88 100644
--- a/clang/lib/Serialization/GeneratePCH.cpp
+++ b/clang/lib/Serialization/GeneratePCH.cpp
@@ -30,11 +30,11 @@ PCHGenerator::PCHGenerator(
bool AllowASTWithErrors, bool IncludeTimestamps,
bool BuildingImplicitModule, bool GeneratingReducedBMI)
: PP(PP), Subject(&PP), OutputFile(OutputFile), isysroot(isysroot.str()),
- Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
- Writer(Stream, this->Buffer->Data, ModCache, CodeGenOpts, Extensions,
+ Buffer(std::move(Buffer)),
+ Writer(Stream, Stream.getBuffer(), ModCache, CodeGenOpts, Extensions,
IncludeTimestamps, BuildingImplicitModule, GeneratingReducedBMI),
AllowASTWithErrors(AllowASTWithErrors) {
- this->Buffer->IsComplete = false;
+ this->Buffer->setIsComplete(false);
}
PCHGenerator::~PCHGenerator() {
@@ -84,7 +84,9 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
Buffer->Signature = Writer.WriteAST(Subject, OutputFile, Module, isysroot);
- Buffer->IsComplete = true;
+ Stream.FlushToWord();
+ Buffer->Data.assign(std::move(Stream.getBuffer()));
+ Buffer->setIsComplete(true);
}
ASTMutationListener *PCHGenerator::GetASTMutationListener() {
@@ -131,7 +133,7 @@ void CXX20ModulesGenerator::HandleTranslationUnit(ASTContext &Ctx) {
return;
}
- *OS << getBufferPtr()->Data;
+ *OS << StringRef(getBufferPtr()->Data.data(), getBufferPtr()->Data.size());
OS->flush();
}
diff --git a/clang/lib/Serialization/PCHContainerOperations.cpp b/clang/lib/Serialization/PCHContainerOperations.cpp
index 4aedb7debcff2..fa4f568b551c0 100644
--- a/clang/lib/Serialization/PCHContainerOperations.cpp
+++ b/clang/lib/Serialization/PCHContainerOperations.cpp
@@ -35,14 +35,14 @@ class RawPCHContainerGenerator : public ASTConsumer {
~RawPCHContainerGenerator() override = default;
void HandleTranslationUnit(ASTContext &Ctx) override {
- if (Buffer->IsComplete) {
+ if (Buffer->getIsComplete()) {
// Make sure it hits disk now.
- *OS << Buffer->Data;
+ *OS << StringRef(Buffer->Data.data(), Buffer->Data.size());
OS->flush();
}
// Free the space of the temporary buffer.
llvm::SmallVector<char, 0> Empty;
- Buffer->Data = std::move(Empty);
+ Buffer->Data.assign(std::move(Empty));
}
};
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index 3997da0ba5dc5..d3de442a25041 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -22,6 +22,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
@@ -216,20 +217,25 @@ static void describeUninitializedArgumentInCall(const CallEvent &Call,
namespace {
class FindUninitializedField {
public:
- using FieldChainTy = SmallVector<const FieldDecl *, 10>;
- FieldChainTy FieldChain;
+ struct FieldChainTy : ArrayRef<const FieldDecl *> {
+ explicit FieldChainTy(ArrayRef<const FieldDecl *> Fields)
+ : ArrayRef(Fields) {}
+ };
+ llvm::SmallVectorWithFlags<const FieldDecl *, 10> FieldChain;
private:
StoreManager &StoreMgr;
MemRegionManager &MrMgr;
Store store;
- bool FindNotUninitialized;
+ bool getFindNotUninitialized() const { return FieldChain.getFlag(0); }
+ void setFindNotUninitialized(bool Value) { FieldChain.setFlag(0, Value); }
public:
FindUninitializedField(StoreManager &storeMgr, MemRegionManager &mrMgr,
Store s, bool FindNotUninitialized = false)
- : StoreMgr(storeMgr), MrMgr(mrMgr), store(s),
- FindNotUninitialized(FindNotUninitialized) {}
+ : FieldChain(decltype(this->FieldChain)::withFlags(
+ unsigned(FindNotUninitialized))),
+ StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
bool Find(const TypedValueRegion *R) {
QualType T = R->getValueType();
@@ -243,18 +249,18 @@ class FindUninitializedField {
FieldChain.push_back(I);
T = I->getType();
if (T->isStructureType()) {
- if (FindNotUninitialized ? !Find(FR) : Find(FR))
- return !FindNotUninitialized;
+ if (getFindNotUninitialized() ? !Find(FR) : Find(FR))
+ return !getFindNotUninitialized();
} else {
SVal V = StoreMgr.getBinding(store, loc::MemRegionVal(FR));
- if (FindNotUninitialized ? !V.isUndef() : V.isUndef())
- return !FindNotUninitialized;
+ if (getFindNotUninitialized() ? !V.isUndef() : V.isUndef())
+ return !getFindNotUninitialized();
}
FieldChain.pop_back();
}
}
- return FindNotUninitialized;
+ return getFindNotUninitialized();
}
};
} // namespace
@@ -363,7 +369,8 @@ bool CallAndMessageChecker::uninitRefOrPointer(CheckerContext &C, SVal V,
std::string Msg = llvm::formatv(
"{0}{1} function call argument {2} an uninitialized value{3}; {4}",
(ArgumentNumber + 1), llvm::getOrdinalSuffix(ArgumentNumber + 1),
- ParamT->isPointerType() ? "points to" : "is", F.FieldChain,
+ ParamT->isPointerType() ? "points to" : "is",
+ FindUninitializedField::FieldChainTy(F.FieldChain),
DescribeArgument(/*ArgIsStruct=*/true));
auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
R->addRange(Call.getArgSourceRange(ArgumentNumber));
@@ -423,7 +430,7 @@ bool CallAndMessageChecker::PreVisitProcessArg(
if (ExplodedNode *N = C.generateErrorNode()) {
std::string Msg = llvm::formatv(
"Passed-by-value struct argument contains uninitialized data{0}",
- F.FieldChain);
+ FindUninitializedField::FieldChainTy(F.FieldChain));
// Generate a report for this bug.
auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
diff --git a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
index 19aeebf588eeb..741f7fc74fba1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -29,6 +29,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Unicode.h"
#include <optional>
@@ -1193,10 +1194,15 @@ class PluralMisuseChecker : public Checker<check::ASTCodeBody> {
// This functions like a stack. We push on any IfStmt or
// ConditionalOperator that matches the condition
// and pop it off when we leave that statement
- llvm::SmallVector<const clang::Stmt *, 8> MatchingStatements;
+ llvm::SmallVectorWithFlags<const clang::Stmt *, 8> MatchingStatements;
// This is true when we are the direct-child of a
// matching statement
- bool InMatchingStatement = false;
+ bool getInMatchingStatement() const {
+ return MatchingStatements.getFlag(0);
+ }
+ void setInMatchingStatement(bool Value) {
+ MatchingStatements.setFlag(0, Value);
+ }
public:
explicit MethodCrawler(BugReporter &InBR, const CheckerBase *Checker,
@@ -1269,7 +1275,7 @@ bool PluralMisuseChecker::MethodCrawler::isCheckingPlurality(
// string. Raise a diagnostic when this is in a statement that matches
// the condition.
bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(CallExpr *CE) {
- if (InMatchingStatement) {
+ if (getInMatchingStatement()) {
if (const FunctionDecl *FD = CE->getDirectCallee()) {
std::string NormalizedName =
StringRef(FD->getNameInfo().getAsString()).lower();
@@ -1299,7 +1305,7 @@ bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
if (odInfo->isStr("NSBundle") &&
ME->getSelector().getAsString() == "localizedStringForKey:value:table:") {
- if (InMatchingStatement) {
+ if (getInMatchingStatement()) {
reportPluralMisuseError(ME);
}
}
@@ -1319,11 +1325,11 @@ bool PluralMisuseChecker::MethodCrawler::EndVisitIfStmt(IfStmt *I) {
MatchingStatements.pop_back();
if (!MatchingStatements.empty()) {
if (MatchingStatements.back() != nullptr) {
- InMatchingStatement = true;
+ setInMatchingStatement(true);
return true;
}
}
- InMatchingStatement = false;
+ setInMatchingStatement(false);
return true;
}
@@ -1334,10 +1340,10 @@ bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(IfStmt *I) {
Condition = Condition->IgnoreParenImpCasts();
if (isCheckingPlurality(Condition)) {
MatchingStatements.push_back(I);
- InMatchingStatement = true;
+ setInMatchingStatement(true);
} else {
MatchingStatements.push_back(nullptr);
- InMatchingStatement = false;
+ setInMatchingStatement(false);
}
return true;
@@ -1350,11 +1356,11 @@ bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
MatchingStatements.pop_back();
if (!MatchingStatements.empty()) {
if (MatchingStatements.back() != nullptr)
- InMatchingStatement = true;
+ setInMatchingStatement(true);
else
- InMatchingStatement = false;
+ setInMatchingStatement(false);
} else {
- InMatchingStatement = false;
+ setInMatchingStatement(false);
}
return true;
}
@@ -1364,10 +1370,10 @@ bool PluralMisuseChecker::MethodCrawler::VisitConditionalOperator(
const Expr *Condition = C->getCond()->IgnoreParenImpCasts();
if (isCheckingPlurality(Condition)) {
MatchingStatements.push_back(C);
- InMatchingStatement = true;
+ setInMatchingStatement(true);
} else {
MatchingStatements.push_back(nullptr);
- InMatchingStatement = false;
+ setInMatchingStatement(false);
}
return true;
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index db307d3ac549f..f2b43ce3711d3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -23,6 +23,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace ento;
@@ -476,7 +477,7 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
CheckerContext &Ctx;
ProgramStateRef State;
const StackFrame *PoppedFrame;
- const bool TopFrame;
+ bool getTopFrame() const { return V.getFlag(0); }
/// Look for stack variables referring to popped stack variables.
/// Returns true only if it found some dangling stack variables
@@ -509,7 +510,7 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
if (isa<StackArgumentsSpaceRegion>(ReferrerMemSpace) &&
// Not a simple ptr (int*) but something deeper, e.g. int**
isa<SymbolicRegion>(Referrer->getBaseRegion()) &&
- ReferrerStackSpace->getStackFrame() == PoppedFrame && TopFrame) {
+ ReferrerStackSpace->getStackFrame() == PoppedFrame && getTopFrame()) {
// Output parameter of a top-level function
V.emplace_back(Referrer, Referred);
return true;
@@ -527,7 +528,9 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
}
public:
- SmallVector<std::pair<const MemRegion *, const MemRegion *>, 10> V;
+ llvm::SmallVectorWithFlags<std::pair<const MemRegion *, const MemRegion *>,
+ 10>
+ V;
// ExcludedRegions are skipped from reporting.
// I.e., if a referrer in this set, skip the related bug report.
// It is useful to avoid false positive for the variables that were
@@ -536,7 +539,7 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
CallBack(CheckerContext &CC, bool TopFrame)
: Ctx(CC), State(CC.getState()), PoppedFrame(CC.getStackFrame()),
- TopFrame(TopFrame) {}
+ V(decltype(this->V)::withFlags(unsigned(TopFrame))) {}
bool HandleBinding(StoreManager &SMgr, Store S, const MemRegion *Region,
SVal Val) override {
diff --git a/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp b/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
index 285d4a40157db..f2d4f991c3516 100644
--- a/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
+++ b/clang/lib/Tooling/Inclusions/HeaderIncludes.cpp
@@ -291,13 +291,16 @@ IncludeCategoryManager::IncludeCategoryManager(const IncludeStyle &Style,
? llvm::Regex::NoFlags
: llvm::Regex::IgnoreCase);
}
- IsMainFile = FileName.ends_with(".c") || FileName.ends_with(".cc") ||
- FileName.ends_with(".cpp") || FileName.ends_with(".c++") ||
- FileName.ends_with(".cxx") || FileName.ends_with(".m") ||
- FileName.ends_with(".mm");
+ setIsMainFile(FileName.ends_with(".c") || FileName.ends_with(".cc") ||
+ FileName.ends_with(".cpp") || FileName.ends_with(".c++") ||
+ FileName.ends_with(".cxx") || FileName.ends_with(".m") ||
+ FileName.ends_with(".mm"));
if (!Style.IncludeIsMainSourceRegex.empty()) {
llvm::Regex MainFileRegex(Style.IncludeIsMainSourceRegex);
- IsMainFile |= MainFileRegex.match(FileName);
+ [&] {
+ auto PackedFlagValue = MainFileRegex.match(FileName);
+ return setIsMainFile(getIsMainFile() | PackedFlagValue);
+ }();
}
}
@@ -309,7 +312,8 @@ int IncludeCategoryManager::getIncludePriority(StringRef IncludeName,
Ret = Style.IncludeCategories[i].Priority;
break;
}
- if (CheckMainHeader && IsMainFile && Ret > 0 && isMainHeader(IncludeName))
+ if (CheckMainHeader && getIsMainFile() && Ret > 0 &&
+ isMainHeader(IncludeName))
Ret = 0;
return Ret;
}
@@ -324,7 +328,8 @@ int IncludeCategoryManager::getSortIncludePriority(StringRef IncludeName,
Ret = Style.IncludeCategories[i].Priority;
break;
}
- if (CheckMainHeader && IsMainFile && Ret > 0 && isMainHeader(IncludeName))
+ if (CheckMainHeader && getIsMainFile() && Ret > 0 &&
+ isMainHeader(IncludeName))
Ret = 0;
return Ret;
}
diff --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
index 152e568e00384..2ca1013b93ce2 100644
--- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -162,18 +162,18 @@ int main(int argc, const char **argv) {
/// Class to store bundler options in standard (non-cl::opt) data structures
// Avoid using cl::opt variables after these assignments when possible
OffloadBundlerConfig BundlerConfig;
- BundlerConfig.AllowMissingBundles = AllowMissingBundles;
- BundlerConfig.CheckInputArchive = CheckInputArchive;
- BundlerConfig.PrintExternalCommands = PrintExternalCommands;
- BundlerConfig.HipOpenmpCompatible = HipOpenmpCompatible;
+ BundlerConfig.setAllowMissingBundles(AllowMissingBundles);
+ BundlerConfig.setCheckInputArchive(CheckInputArchive);
+ BundlerConfig.setPrintExternalCommands(PrintExternalCommands);
+ BundlerConfig.setHipOpenmpCompatible(HipOpenmpCompatible);
BundlerConfig.BundleAlignment = BundleAlignment;
BundlerConfig.FilesType = FilesType;
BundlerConfig.ObjcopyPath = "";
// Do not override the default value Compress and Verbose in BundlerConfig.
if (Compress.getNumOccurrences() > 0)
- BundlerConfig.Compress = Compress;
+ BundlerConfig.setCompress(Compress);
if (Verbose.getNumOccurrences() > 0)
- BundlerConfig.Verbose = Verbose;
+ BundlerConfig.setVerbose(Verbose);
if (CompressionLevel.getNumOccurrences() > 0)
BundlerConfig.CompressionLevel = CompressionLevel;
@@ -187,7 +187,7 @@ int main(int argc, const char **argv) {
BundlerConfig.HostInputIndex = ~0u;
/// Whether not having host target is allowed.
- BundlerConfig.AllowNoHost = false;
+ BundlerConfig.setAllowNoHost(false);
auto reportError = [argv](Error E) {
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0]));
@@ -283,7 +283,7 @@ int main(int argc, const char **argv) {
});
}
- if (BundlerConfig.CheckInputArchive) {
+ if (BundlerConfig.getCheckInputArchive()) {
if (!Unbundle) {
return reportError(createStringError(
errc::invalid_argument, "-check-input-archive cannot be used while "
@@ -415,12 +415,12 @@ int main(int argc, const char **argv) {
// HIP uses clang-offload-bundler to bundle device-only compilation results
// for multiple GPU archs, therefore allow no host target if all entries
// are for HIP.
- BundlerConfig.AllowNoHost = HIPOnly;
+ BundlerConfig.setAllowNoHost(HIPOnly);
// Host triple is not really needed for unbundling operation, so do not
// treat missing host triple as error if we do unbundling.
if ((Unbundle && HostTargetNum > 1) ||
- (!Unbundle && HostTargetNum != 1 && !BundlerConfig.AllowNoHost)) {
+ (!Unbundle && HostTargetNum != 1 && !BundlerConfig.getAllowNoHost())) {
return reportError(createStringError(
errc::invalid_argument,
"expecting exactly one host target but got " + Twine(HostTargetNum)));
diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 4c6ff23de71df..056ddc81374b9 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -508,9 +508,9 @@ class FullDeps {
for (auto &&ModID : ModuleIDs) {
auto &MD = Modules[ModID];
JOS.object([&] {
- if (MD.IsInStableDirectories)
+ if (MD.getIsInStableDirectories())
JOS.attribute("is-in-stable-directories",
- MD.IsInStableDirectories);
+ MD.getIsInStableDirectories());
JOS.attributeArray("clang-module-deps",
toJSONSorted(JOS, MD.ClangModuleDeps));
JOS.attribute("clang-modulemap-file",
@@ -529,8 +529,11 @@ class FullDeps {
JOS.value(FileDep);
});
});
- JOS.attributeArray("link-libraries",
- toJSONSorted(JOS, MD.LinkLibraries));
+ JOS.attributeArray(
+ "link-libraries",
+ toJSONSorted(JOS, SmallVector<Module::LinkLibrary, 2>(
+ MD.LinkLibraries.begin(),
+ MD.LinkLibraries.end())));
JOS.attribute("name", StringRef(MD.ID.ModuleName));
});
}
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index 077cd69ce4e2c..23c730f98af5a 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -19,6 +19,7 @@
#include "clang/Frontend/Utils.h"
#include "clang/Options/Options.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/DataLayout.h"
@@ -102,7 +103,8 @@ struct AssemblerInvocation {
std::string DwarfDebugFlags;
std::string DwarfDebugProducer;
std::string DebugCompilationDir;
- llvm::SmallVector<std::pair<std::string, std::string>, 0> DebugPrefixMap;
+ llvm::SmallVectorWithFlags<std::pair<std::string, std::string>, 0, 2>
+ DebugPrefixMap;
llvm::DebugCompressionType CompressDebugSections =
llvm::DebugCompressionType::None;
std::string MainFileName;
@@ -121,10 +123,12 @@ struct AssemblerInvocation {
FT_Obj ///< Object file output.
};
FileType OutputType;
- LLVM_PREFERRED_TYPE(bool)
- unsigned ShowHelp : 1;
- LLVM_PREFERRED_TYPE(bool)
- unsigned ShowVersion : 1;
+ unsigned getShowHelp() const { return DebugPrefixMap.getFlag(0); }
+ void setShowHelp(unsigned Value) { DebugPrefixMap.setFlag(0, (Value & 1)); }
+ unsigned getShowVersion() const { return DebugPrefixMap.getFlag(1); }
+ void setShowVersion(unsigned Value) {
+ DebugPrefixMap.setFlag(1, (Value & 1));
+ }
/// @}
/// @name Transliterate Options
@@ -352,8 +356,8 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
} else
Opts.OutputType = FileType(OutputType);
}
- Opts.ShowHelp = Args.hasArg(OPT_help);
- Opts.ShowVersion = Args.hasArg(OPT_version);
+ Opts.setShowHelp(Args.hasArg(OPT_help));
+ Opts.setShowVersion(Args.hasArg(OPT_version));
// Transliterate Options
Opts.OutputAsmVariant =
@@ -704,7 +708,7 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
if (!AssemblerInvocation::CreateFromArgs(Asm, Argv, Diags))
return 1;
- if (Asm.ShowHelp) {
+ if (Asm.getShowHelp()) {
getDriverOptTable().printHelp(
llvm::outs(), "clang -cc1as [options] file...",
"Clang Integrated Assembler", /*ShowHidden=*/false,
@@ -716,7 +720,7 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
// Honor -version.
//
// FIXME: Use a better -version message?
- if (Asm.ShowVersion) {
+ if (Asm.getShowVersion()) {
llvm::cl::PrintVersionMessage();
return 0;
}
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index af96812e9ebd9..82e907aa3bec0 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -139,9 +139,9 @@ static T checkEnvVar(const char *EnvOptSet, const char *EnvOptFile,
}
static bool SetBackdoorDriverOutputsFromEnvVars(Driver &TheDriver) {
- TheDriver.CCPrintOptions =
+ TheDriver.setCCPrintOptions(
checkEnvVar<bool>("CC_PRINT_OPTIONS", "CC_PRINT_OPTIONS_FILE",
- TheDriver.CCPrintOptionsFilename);
+ TheDriver.CCPrintOptionsFilename));
if (checkEnvVar<bool>("CC_PRINT_HEADERS", "CC_PRINT_HEADERS_FILE",
TheDriver.CCPrintHeadersFilename)) {
TheDriver.CCPrintHeadersFormat = HIFMT_Textual;
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 8d246d41f31f6..e66452a8c6d1c 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -47,6 +47,7 @@
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
@@ -291,14 +292,14 @@ bool CursorVisitor::visitFileRegion() {
unsigned Offset = Begin.second;
unsigned Length = End.second - Begin.second;
- if (!VisitDeclsOnly && !VisitPreprocessorLast)
+ if (!getVisitDeclsOnly() && !getVisitPreprocessorLast())
if (visitPreprocessedEntitiesInRegion())
return true; // visitation break.
if (visitDeclsFromFileRegion(File, Offset, Length))
return true; // visitation break.
- if (!VisitDeclsOnly && VisitPreprocessorLast)
+ if (!getVisitDeclsOnly() && getVisitPreprocessorLast())
return visitPreprocessedEntitiesInRegion();
return false;
@@ -535,7 +536,8 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
CXTranslationUnit TU = getCursorTU(Cursor);
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
- int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
+ int VisitOrder[2] = {getVisitPreprocessorLast(),
+ !getVisitPreprocessorLast()};
for (unsigned I = 0; I != 2; ++I) {
if (VisitOrder[I]) {
if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
@@ -7906,7 +7908,12 @@ class AnnotateTokensWorker {
unsigned PreprocessingTokIdx;
CursorVisitor AnnotateVis;
SourceManager &SrcMgr;
- bool HasContextSensitiveKeywords;
+ bool getHasContextSensitiveKeywords() const {
+ return PostChildrenInfos.getFlag(0);
+ }
+ void setHasContextSensitiveKeywords(bool Value) {
+ PostChildrenInfos.setFlag(0, Value);
+ }
struct PostChildrenAction {
CXCursor cursor;
@@ -7921,7 +7928,7 @@ class AnnotateTokensWorker {
unsigned BeforeChildrenTokenIdx;
PostChildrenActions ChildActions;
};
- SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
+ llvm::SmallVectorWithFlags<PostChildrenInfo, 8> PostChildrenInfos;
CXToken &getTok(unsigned Idx) {
assert(Idx < NumTokens);
@@ -7958,8 +7965,7 @@ class AnnotateTokensWorker {
/*VisitIncludedEntities=*/false, RegionOfInterest,
/*VisitDeclsOnly=*/false,
AnnotateTokensPostChildrenVisitor),
- SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
- HasContextSensitiveKeywords(false) {}
+ SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()) {}
void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
@@ -7975,7 +7981,7 @@ class AnnotateTokensWorker {
/// Determine whether the annotator saw any cursors that have
/// context-sensitive keywords.
bool hasContextSensitiveKeywords() const {
- return HasContextSensitiveKeywords;
+ return getHasContextSensitiveKeywords();
}
~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
@@ -8126,13 +8132,13 @@ enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
if (IsIgnoredChildCursor(cursor))
return CXChildVisit_Continue;
- if (!HasContextSensitiveKeywords) {
+ if (!getHasContextSensitiveKeywords()) {
// Objective-C properties can have context-sensitive keywords.
if (cursor.kind == CXCursor_ObjCPropertyDecl) {
if (const ObjCPropertyDecl *Property =
dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
- HasContextSensitiveKeywords =
- Property->getPropertyAttributesAsWritten() != 0;
+ setHasContextSensitiveKeywords(
+ Property->getPropertyAttributesAsWritten() != 0);
}
// Objective-C methods can have context-sensitive keywords.
else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
@@ -8140,11 +8146,11 @@ enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
if (const ObjCMethodDecl *Method =
dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
if (Method->getObjCDeclQualifier())
- HasContextSensitiveKeywords = true;
+ setHasContextSensitiveKeywords(true);
else {
for (const auto *P : Method->parameters()) {
if (P->getObjCDeclQualifier()) {
- HasContextSensitiveKeywords = true;
+ setHasContextSensitiveKeywords(true);
break;
}
}
@@ -8156,7 +8162,7 @@ enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
if (const CXXMethodDecl *Method =
dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
- HasContextSensitiveKeywords = true;
+ setHasContextSensitiveKeywords(true);
}
}
// C++ classes can have context-sensitive keywords.
@@ -8166,7 +8172,7 @@ enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
if (const Decl *D = getCursorDecl(cursor))
if (D->hasAttr<FinalAttr>())
- HasContextSensitiveKeywords = true;
+ setHasContextSensitiveKeywords(true);
}
}
@@ -9501,7 +9507,7 @@ int clang_Module_isSystem(CXModule CXMod) {
if (!CXMod)
return 0;
Module *Mod = static_cast<Module *>(CXMod);
- return Mod->IsSystem;
+ return Mod->getIsSystem();
}
unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
diff --git a/clang/tools/libclang/CursorVisitor.h b/clang/tools/libclang/CursorVisitor.h
index 1b359d2920e11..e0e46c571b1be 100644
--- a/clang/tools/libclang/CursorVisitor.h
+++ b/clang/tools/libclang/CursorVisitor.h
@@ -14,6 +14,7 @@
#include "Index_Internal.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/TypeLocVisitor.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <optional>
namespace clang {
@@ -97,11 +98,13 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
/// Whether we should visit the preprocessing record entries last,
/// after visiting other declarations.
- bool VisitPreprocessorLast;
+ bool getVisitPreprocessorLast() const { return WorkListCache.getFlag(0); }
+ void setVisitPreprocessorLast(bool Value) { WorkListCache.setFlag(0, Value); }
/// Whether we should visit declarations or preprocessing record
/// entries that are #included inside the \arg RegionOfInterest.
- bool VisitIncludedEntities;
+ bool getVisitIncludedEntities() const { return WorkListCache.getFlag(1); }
+ void setVisitIncludedEntities(bool Value) { WorkListCache.setFlag(1, Value); }
/// When valid, a source range to which the cursor should restrict
/// its search.
@@ -109,7 +112,8 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
/// Whether we should only visit declarations and not preprocessing
/// record entries.
- bool VisitDeclsOnly;
+ bool getVisitDeclsOnly() const { return WorkListCache.getFlag(2); }
+ void setVisitDeclsOnly(bool Value) { WorkListCache.setFlag(2, Value); }
// FIXME: Eventually remove. This part of a hack to support proper
// iteration over all Decls contained lexically within an ObjC container.
@@ -120,7 +124,7 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
// Cache of pre-allocated worklists for data-recursion walk of Stmts.
SmallVector<VisitorWorkList *, 5> WorkListFreeList;
- SmallVector<VisitorWorkList *, 5> WorkListCache;
+ llvm::SmallVectorWithFlags<VisitorWorkList *, 5, 3> WorkListCache;
using DeclVisitor<CursorVisitor, bool>::Visit;
using TypeLocVisitor<CursorVisitor, bool>::Visit;
@@ -162,10 +166,12 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
PostChildrenVisitorTy PostChildrenVisitor = nullptr)
: TU(TU), AU(cxtu::getASTUnit(TU)), Visitor(Visitor),
PostChildrenVisitor(PostChildrenVisitor), ClientData(ClientData),
- VisitPreprocessorLast(VisitPreprocessorLast),
- VisitIncludedEntities(VisitIncludedPreprocessingEntries),
- RegionOfInterest(RegionOfInterest), VisitDeclsOnly(VisitDeclsOnly),
- DI_current(nullptr), FileDI_current(nullptr) {
+ RegionOfInterest(RegionOfInterest), DI_current(nullptr),
+ FileDI_current(nullptr),
+ WorkListCache(decltype(WorkListCache)::withFlags(
+ unsigned(VisitPreprocessorLast) |
+ (unsigned(VisitIncludedPreprocessingEntries) << 1) |
+ (unsigned(VisitDeclsOnly) << 2))) {
Parent.kind = CXCursor_NoDeclFound;
Parent.data[0] = nullptr;
Parent.data[1] = nullptr;
@@ -193,7 +199,9 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
bool visitPreprocessedEntitiesInRegion();
- bool shouldVisitIncludedEntities() const { return VisitIncludedEntities; }
+ bool shouldVisitIncludedEntities() const {
+ return getVisitIncludedEntities();
+ }
template <typename InputIterator>
bool visitPreprocessedEntities(InputIterator First, InputIterator Last,
diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp
index 0fd2eb36898ea..a72f7881e583b 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -28,6 +28,7 @@
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/VirtualFileSystem.h"
@@ -148,11 +149,12 @@ class ParsedSrcLocationsTracker {
/// constructed.
llvm::DenseSet<PPRegion> ParsedRegionsSnapshot;
/// Regions that were queried during this instance lifetime.
- SmallVector<PPRegion, 32> NewParsedRegions;
+ llvm::SmallVectorWithFlags<PPRegion, 32> NewParsedRegions;
/// Caching the last queried region.
PPRegion LastRegion;
- bool LastIsParsed;
+ bool getLastIsParsed() const { return NewParsedRegions.getFlag(0); }
+ void setLastIsParsed(bool Value) { NewParsedRegions.setFlag(0, Value); }
public:
/// Creates snapshot of \p ParsedRegionsStorage.
@@ -173,17 +175,17 @@ class ParsedSrcLocationsTracker {
// Check common case, consecutive functions in the same region.
if (LastRegion == region)
- return LastIsParsed;
+ return getLastIsParsed();
LastRegion = region;
// Source locations can't be revisited during single TU parsing.
// That means if we hit the same region again, it's a different location in
// the same region and so the "is parsed" value from the snapshot is still
// correct.
- LastIsParsed = ParsedRegionsSnapshot.count(region);
- if (!LastIsParsed)
+ setLastIsParsed(ParsedRegionsSnapshot.count(region));
+ if (!getLastIsParsed())
NewParsedRegions.emplace_back(std::move(region));
- return LastIsParsed;
+ return getLastIsParsed();
}
/// Updates ParsedRegionsStorage with newly parsed regions.
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 59aac4c507772..f7ae892860428 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -887,9 +887,9 @@ namespace {
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
<< "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
<< getLowerName() << "_end(); I != E; ++I) {\n";
- OS << " if (I->IsTarget && I->IsTargetSync)\n";
+ OS << " if (I->isTarget() && I->isTargetSync())\n";
OS << " OS << \" Target_TargetSync\";\n";
- OS << " else if (I->IsTarget)\n";
+ OS << " else if (I->isTarget())\n";
OS << " OS << \" Target\";\n";
OS << " else\n";
OS << " OS << \" TargetSync\";\n";
@@ -906,7 +906,7 @@ namespace {
OS << " bool IsTarget = Record.readBool();\n";
OS << " bool IsTargetSync = Record.readBool();\n";
OS << " OMPInteropInfo Info(IsTarget, IsTargetSync);\n";
- OS << " Info.HasPreferAttrs = Record.readBool();\n";
+ OS << " Info.setPreferAttrs(Record.readBool());\n";
OS << " unsigned prefsSize = Record.readInt();\n";
OS << " Info.Prefs.reserve(prefsSize);\n";
OS << " for (unsigned J = 0; J < prefsSize; ++J) {\n";
@@ -928,9 +928,9 @@ namespace {
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
<< "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
<< getLowerName() << "_end(); I != E; ++I) {\n";
- OS << " Record.writeBool(I->IsTarget);\n";
- OS << " Record.writeBool(I->IsTargetSync);\n";
- OS << " Record.writeBool(I->HasPreferAttrs);\n";
+ OS << " Record.writeBool(I->isTarget());\n";
+ OS << " Record.writeBool(I->isTargetSync());\n";
+ OS << " Record.writeBool(I->hasPreferAttrs());\n";
OS << " Record.push_back(I->Prefs.size());\n";
OS << " for (auto &P : I->Prefs) {\n";
OS << " Record.writeBool(P.Fr != nullptr);\n";
diff --git a/clang/utils/TableGen/HLSLEmitter.cpp b/clang/utils/TableGen/HLSLEmitter.cpp
index c37b7bf27df19..49bcd3bfbee21 100644
--- a/clang/utils/TableGen/HLSLEmitter.cpp
+++ b/clang/utils/TableGen/HLSLEmitter.cpp
@@ -15,6 +15,7 @@
#include "TableGenBackends.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
@@ -238,19 +239,23 @@ struct OverloadContext {
TypeInfo RetType;
/// Per-argument metadata describing type and variation behavior.
- SmallVector<TypeInfo, 4> Args;
+ llvm::SmallVectorWithFlags<TypeInfo, 4, 4> Args;
/// Whether to emit the function as constexpr.
- bool IsConstexpr = false;
+ bool getIsConstexpr() const { return Args.getFlag(0); }
+ void setIsConstexpr(bool Value) { Args.setFlag(0, Value); }
/// Whether to emit the __attribute__((convergent)) annotation.
- bool IsConvergent = false;
+ bool getIsConvergent() const { return Args.getFlag(1); }
+ void setIsConvergent(bool Value) { Args.setFlag(1, Value); }
/// Whether any fixed arg has a 16-bit integer type (e.g. int16_t).
- bool Uses16BitType = false;
+ bool getUses16BitType() const { return Args.getFlag(2); }
+ void setUses16BitType(bool Value) { Args.setFlag(2, Value); }
/// Whether any fixed arg has a conditionally-16-bit type (half).
- bool UsesConditionally16BitType = false;
+ bool getUsesConditionally16BitType() const { return Args.getFlag(3); }
+ void setUsesConditionally16BitType(bool Value) { Args.setFlag(3, Value); }
explicit OverloadContext(raw_ostream &OS) : OS(OS) {}
};
@@ -277,10 +282,10 @@ static void emitDeclaration(const OverloadContext &Ctx, StringRef RetType,
if (!HasBody)
OS << "_HLSL_BUILTIN_ALIAS(" << Ctx.Builtin << ")\n";
- if (Ctx.IsConvergent)
+ if (Ctx.getIsConvergent())
OS << "__attribute__((convergent)) ";
if (HasBody)
- OS << (Ctx.IsConstexpr ? "constexpr " : "inline ");
+ OS << (Ctx.getIsConstexpr() ? "constexpr " : "inline ");
OS << RetType << " " << Ctx.FuncName << "(";
{
@@ -355,15 +360,17 @@ static void buildOverloadContext(const Record *R, OverloadContext &Ctx) {
Ctx.DetailFunc = R->getValueAsString("DetailFunc");
Ctx.Body = R->getValueAsString("Body");
Ctx.FuncName = R->getValueAsString("Name");
- Ctx.IsConstexpr = R->getValueAsBit("IsConstexpr");
- Ctx.IsConvergent = R->getValueAsBit("IsConvergent");
+ Ctx.setIsConstexpr(R->getValueAsBit("IsConstexpr"));
+ Ctx.setIsConvergent(R->getValueAsBit("IsConvergent"));
// Note use of 16-bit fixed types in the overload context.
auto Update16BitFlags = [&Ctx](const Record *Rec) {
const Record *ElemTy = getElementTypeRecord(Rec);
- Ctx.Uses16BitType |= ElemTy->getValueAsBit("Is16Bit");
- Ctx.UsesConditionally16BitType |=
- ElemTy->getValueAsBit("IsConditionally16Bit");
+ Ctx.setUses16BitType(int(Ctx.getUses16BitType()) |
+ (ElemTy->getValueAsBit("Is16Bit")));
+ Ctx.setUsesConditionally16BitType(
+ int(Ctx.getUsesConditionally16BitType()) |
+ (ElemTy->getValueAsBit("IsConditionally16Bit")));
};
// Resolve return and argument types.
@@ -423,7 +430,8 @@ static void buildWorklist(const Record *R,
// This is for HLSLBuiltin records that don't use Varying types.
if (VaryingTypeRecords.empty()) {
TypeWorkItem Item;
- SetAvailability(Item, Ctx.Uses16BitType, Ctx.UsesConditionally16BitType);
+ SetAvailability(Item, Ctx.getUses16BitType(),
+ Ctx.getUsesConditionally16BitType());
Worklist.push_back(Item);
return;
}
@@ -437,8 +445,8 @@ static void buildWorklist(const Record *R,
for (const Record *ElemTy : VaryingTypeRecords) {
TypeWorkItem Item;
Item.ElemType = ElemTy->getValueAsString("Name");
- bool Is16Bit = Ctx.Uses16BitType || ElemTy->getValueAsBit("Is16Bit");
- bool IsCond16Bit = Ctx.UsesConditionally16BitType ||
+ bool Is16Bit = Ctx.getUses16BitType() || ElemTy->getValueAsBit("Is16Bit");
+ bool IsCond16Bit = Ctx.getUsesConditionally16BitType() ||
ElemTy->getValueAsBit("IsConditionally16Bit");
SetAvailability(Item, Is16Bit, IsCond16Bit);
Worklist.push_back(Item);
diff --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp
index e567a27032d12..ccfeb97c7c305 100644
--- a/clang/utils/TableGen/NeonEmitter.cpp
+++ b/clang/utils/TableGen/NeonEmitter.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
@@ -326,24 +327,28 @@ class Intrinsic {
std::string TargetGuard;
/// Set if the Unavailable bit is 1. This means we don't generate a body,
/// just an "unavailable" attribute on a declaration.
- bool IsUnavailable;
+ bool getIsUnavailable() const { return ImmChecks.getFlag(0); }
+ void setIsUnavailable(bool Value) { ImmChecks.setFlag(0, Value); }
/// Is this intrinsic safe for big-endian? or does it need its arguments
/// reversing?
- bool BigEndianSafe;
+ bool getBigEndianSafe() const { return ImmChecks.getFlag(1); }
+ void setBigEndianSafe(bool Value) { ImmChecks.setFlag(1, Value); }
/// The types of return value [0] and parameters [1..].
std::vector<Type> Types;
- SmallVector<ImmCheck, 2> ImmChecks;
+ llvm::SmallVectorWithFlags<ImmCheck, 2, 4> ImmChecks;
/// The index of the key type passed to CGBuiltin.cpp for polymorphic calls.
int PolymorphicKeyType;
/// The local variables defined.
std::map<std::string, Variable, std::less<>> Variables;
/// NeededEarly - set if any other intrinsic depends on this intrinsic.
- bool NeededEarly;
+ bool getNeededEarlyFlag() const { return ImmChecks.getFlag(2); }
+ void setNeededEarlyFlag(bool Value) { ImmChecks.setFlag(2, Value); }
/// UseMacro - set if we should implement using a macro or unset for a
/// function.
- bool UseMacro;
+ bool getUseMacro() const { return ImmChecks.getFlag(3); }
+ void setUseMacro(bool Value) { ImmChecks.setFlag(3, Value); }
/// The set of intrinsics that this intrinsic uses/requires.
std::set<Intrinsic *> Dependencies;
/// The "base type", which is Type('d', OutTS). InBaseType is only
@@ -358,7 +363,7 @@ class Intrinsic {
std::stringstream OS;
bool isBigEndianSafe() const {
- if (BigEndianSafe)
+ if (getBigEndianSafe())
return true;
for (const auto &T : Types){
@@ -375,9 +380,10 @@ class Intrinsic {
bool IsUnavailable, bool BigEndianSafe)
: R(R), Name(Name.str()), OutTS(OutTS), InTS(InTS), CK(CK), Body(Body),
ArchGuard(ArchGuard.str()), TargetGuard(TargetGuard.str()),
- IsUnavailable(IsUnavailable), BigEndianSafe(BigEndianSafe),
- PolymorphicKeyType(0), NeededEarly(false), UseMacro(false),
- BaseType(OutTS, "."), InBaseType(InTS, "."), Emitter(Emitter) {
+ ImmChecks(decltype(ImmChecks)::withFlags(
+ unsigned(IsUnavailable) | (unsigned(BigEndianSafe) << 1))),
+ PolymorphicKeyType(0), BaseType(OutTS, "."), InBaseType(InTS, "."),
+ Emitter(Emitter) {
// Modify the TypeSpec per-argument to get a concrete Type, and create
// known variables for each.
// Types[0] is the return value.
@@ -404,7 +410,7 @@ class Intrinsic {
// taking a scalar float16_t must be implemented as macros.
if (Type.isImmediate() || Type.isPointer() ||
(Type.isScalar() && Type.isHalf()))
- UseMacro = true;
+ setUseMacro(true);
}
int ArgIdx, Kind, TypeArgIdx;
@@ -488,7 +494,7 @@ class Intrinsic {
bool hasBody() const { return Body && !Body->empty(); }
- void setNeededEarly() { NeededEarly = true; }
+ void setNeededEarly() { setNeededEarlyFlag(true); }
bool operator<(const Intrinsic &Other) const {
// Sort lexicographically on a three-tuple (ArchGuard, TargetGuard, Name)
@@ -1204,7 +1210,7 @@ void Intrinsic::initVariables() {
}
void Intrinsic::emitPrototype(StringRef NamePrefix) {
- if (UseMacro) {
+ if (getUseMacro()) {
OS << "#define ";
} else {
OS << "__ai ";
@@ -1225,7 +1231,7 @@ void Intrinsic::emitPrototype(StringRef NamePrefix) {
assert(Variables.find(Name) != Variables.end());
Variable &V = Variables[Name];
- if (!UseMacro)
+ if (!getUseMacro())
OS << V.getType().str() << " ";
OS << V.getName();
}
@@ -1234,7 +1240,7 @@ void Intrinsic::emitPrototype(StringRef NamePrefix) {
}
void Intrinsic::emitOpeningBrace() {
- if (UseMacro)
+ if (getUseMacro())
OS << " __extension__ ({";
else
OS << " {";
@@ -1242,14 +1248,14 @@ void Intrinsic::emitOpeningBrace() {
}
void Intrinsic::emitClosingBrace() {
- if (UseMacro)
+ if (getUseMacro())
OS << "})";
else
OS << "}";
}
void Intrinsic::emitNewLine() {
- if (UseMacro)
+ if (getUseMacro())
OS << " \\\n";
else
OS << "\n";
@@ -1318,7 +1324,7 @@ void Intrinsic::emitReturnReversal() {
void Intrinsic::emitShadowedArgs() {
// Macro arguments are not type-checked like inline function arguments,
// so assign them to local temporaries to get the right type checking.
- if (!UseMacro)
+ if (!getUseMacro())
return;
for (unsigned I = 0; I < getNumParams(); ++I) {
@@ -1464,7 +1470,7 @@ void Intrinsic::emitBody(StringRef CallPrefix) {
void Intrinsic::emitReturn() {
if (RetVar.getType().isVoid())
return;
- if (UseMacro)
+ if (getUseMacro())
OS << " " << RetVar.getName() << ";";
else
OS << " return " << RetVar.getName() << ";";
@@ -1887,7 +1893,7 @@ std::string Intrinsic::generate() {
// If we're needed early, create a non-swapping variant for
// big-endian.
- if (NeededEarly) {
+ if (getNeededEarlyFlag()) {
generateImpl(false, "__noswap_", "__noswap_");
}
OS << "#endif\n\n";
@@ -1905,7 +1911,7 @@ void Intrinsic::generateImpl(bool ReverseArguments,
//
// indexBody() should have set up the Dependencies set by now.
for (auto *I : Dependencies)
- if (I->UseMacro) {
+ if (I->getUseMacro()) {
VariablePostfix = "_" + utostr(Emitter.getUniqueNumber());
break;
}
@@ -1914,7 +1920,7 @@ void Intrinsic::generateImpl(bool ReverseArguments,
emitPrototype(NamePrefix);
- if (IsUnavailable) {
+ if (getIsUnavailable()) {
OS << " __attribute__((unavailable));";
} else {
emitOpeningBrace();
diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index 0f770a3202538..4f237dc864a2e 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -25,6 +25,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/raw_ostream.h"
@@ -181,9 +182,10 @@ class Intrinsic {
uint64_t Flags;
- SmallVector<ImmCheck, 2> ImmChecks;
+ llvm::SmallVectorWithFlags<ImmCheck, 2> ImmChecks;
- bool SetsFPMR;
+ bool getSetsFPMR() const { return ImmChecks.getFlag(0); }
+ void setSetsFPMR(bool Value) { ImmChecks.setFlag(0, Value); }
public:
Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
@@ -292,7 +294,7 @@ class Intrinsic {
private:
std::string getMergeSuffix() const { return MergeSuffix; }
- StringRef getFPMSuffix() const { return SetsFPMR ? "_fpm" : ""; }
+ StringRef getFPMSuffix() const { return getSetsFPMR() ? "_fpm" : ""; }
std::string mangleName(ClassKind LocalCK) const;
std::string mangleLLVMName() const;
std::string replaceTemplatedArgs(std::string Name, TypeSpec TS,
@@ -1041,7 +1043,7 @@ Intrinsic::Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
std::tie(Mod, NumVectors) = getProtoModifier(Proto, I);
SVEType T(BaseTypeSpec, Mod, NumVectors);
Types.push_back(T);
- SetsFPMR = T.isFpm();
+ setSetsFPMR(T.isFpm());
// Add range checks for immediates
if (I > 0) {
@@ -1060,7 +1062,7 @@ Intrinsic::Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
this->Flags |= Emitter.encodeMergeType(MergeTy);
if (hasSplat())
this->Flags |= Emitter.encodeSplatOperand(getSplatIdx());
- if (SetsFPMR)
+ if (getSetsFPMR())
this->Flags |= Emitter.getEnumValueForFlag("SetsFPMR");
}
diff --git a/flang/include/flang/Lower/CallInterface.h b/flang/include/flang/Lower/CallInterface.h
index 2673e61b1a915..926c54dbf38b2 100644
--- a/flang/include/flang/Lower/CallInterface.h
+++ b/flang/include/flang/Lower/CallInterface.h
@@ -30,6 +30,7 @@
#include "flang/Common/reference.h"
#include "flang/Evaluate/characteristics.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <optional>
namespace Fortran::semantics {
@@ -230,7 +231,7 @@ class CallInterface {
/// Is the Fortran result passed as an extra MLIR argument ?
bool mustPassResult() const { return passedResult.has_value(); }
/// Must the MLIR result be saved with a fir.save_result ?
- bool mustSaveResult() const { return saveResult; }
+ bool mustSaveResult() const { return passedArguments.getFlag(0); }
/// Can the associated procedure be called via an implicit interface?
bool canBeCalledViaImplicitInterface() const {
@@ -258,9 +259,9 @@ class CallInterface {
llvm::SmallVector<FirPlaceHolder> outputs;
llvm::SmallVector<FirPlaceHolder> inputs;
mlir::func::FuncOp func;
- llvm::SmallVector<PassedEntity> passedArguments;
+ // Flag 0 records whether the caller must save the result.
+ llvm::SmallVectorWithFlags<PassedEntity> passedArguments;
std::optional<PassedEntity> passedResult;
- bool saveResult = false;
Fortran::lower::AbstractConverter &converter;
/// Store characteristic once created, it is required for further information
diff --git a/flang/include/flang/Lower/PFTBuilder.h b/flang/include/flang/Lower/PFTBuilder.h
index 981a78068c658..57decbdbd2ac7 100644
--- a/flang/include/flang/Lower/PFTBuilder.h
+++ b/flang/include/flang/Lower/PFTBuilder.h
@@ -26,6 +26,7 @@
#include "flang/Semantics/scope.h"
#include "flang/Semantics/semantics.h"
#include "flang/Semantics/symbol.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -420,15 +421,28 @@ struct Evaluation : EvaluationVariant {
// Additional branch targets for multiway branches (computed GO TO,
// arithmetic IF). Empty for single-target branches; the first target is in
// controlSuccessor and the remaining ones are stored here in source order.
- llvm::SmallVector<Evaluation *, 0> extraControlSuccessors;
+ llvm::SmallVectorWithFlags<Evaluation *, 0, 4> extraControlSuccessors;
Evaluation *constructExit{nullptr}; // set for constructs
- bool isNewBlock{false}; // evaluation begins a new basic block
+ bool getIsNewBlock() const { return extraControlSuccessors.getFlag(0); }
+ bool setIsNewBlock(bool Value) {
+ extraControlSuccessors.setFlag(0, Value);
+ return Value;
+ } // evaluation begins a new basic block
ControlFlow controlFlow{ControlFlow::Structured};
- bool negateCondition{false}; // If[Then]Stmt condition must be negated
- bool activeConstruct{false}; // temporarily set for some constructs
+ bool getNegateCondition() const { return extraControlSuccessors.getFlag(1); }
+ void setNegateCondition(bool Value) {
+ extraControlSuccessors.setFlag(1, Value);
+ } // If[Then]Stmt condition must be negated
+ bool getActiveConstruct() const { return extraControlSuccessors.getFlag(2); }
+ void setActiveConstruct(bool Value) {
+ extraControlSuccessors.setFlag(2, Value);
+ } // temporarily set for some constructs
// The enclosing evaluation-list traversal should skip this evaluation once
// because directive lowering already consumed it.
- bool skipNextLowering{false};
+ bool getSkipNextLowering() const { return extraControlSuccessors.getFlag(3); }
+ void setSkipNextLowering(bool Value) {
+ extraControlSuccessors.setFlag(3, Value);
+ }
mlir::Block *block{nullptr}; // isNewBlock block (ActionStmt, ConstructStmt)
int printIndex{0}; // (ActionStmt, ConstructStmt) evaluation index for dumps
};
@@ -794,17 +808,31 @@ struct FunctionLikeUnit : public ProgramUnit {
/// The primary entry point symbol is Null for an anonymous program.
/// A named program symbol has MainProgramDetails. Other symbols have
/// SubprogramDetails. Evaluations are filled in for alternate entries.
- llvm::SmallVector<std::pair<const semantics::Symbol *, Evaluation *>, 1>
+ llvm::SmallVectorWithFlags<std::pair<const semantics::Symbol *, Evaluation *>,
+ 1, 4>
entryPointList{std::pair{nullptr, nullptr}};
/// Current index into entryPointList. Index 0 is the primary entry point.
int activeEntry = 0;
/// Primary result for function subprograms with alternate entries. This
/// is one of the largest result values, not necessarily the first one.
const semantics::Symbol *primaryResult{nullptr};
- bool hasIeeeAccess{false};
- bool mayModifyHaltingMode{false};
- bool mayModifyRoundingMode{false};
- bool mayModifyUnderflowMode{false};
+ bool getHasIeeeAccess() const { return entryPointList.getFlag(0); }
+ void setHasIeeeAccess(bool Value) { entryPointList.setFlag(0, Value); }
+ bool getMayModifyHaltingMode() const { return entryPointList.getFlag(1); }
+ bool setMayModifyHaltingMode(bool Value) {
+ entryPointList.setFlag(1, Value);
+ return Value;
+ }
+ bool getMayModifyRoundingMode() const { return entryPointList.getFlag(2); }
+ bool setMayModifyRoundingMode(bool Value) {
+ entryPointList.setFlag(2, Value);
+ return Value;
+ }
+ bool getMayModifyUnderflowMode() const { return entryPointList.getFlag(3); }
+ bool setMayModifyUnderflowMode(bool Value) {
+ entryPointList.setFlag(3, Value);
+ return Value;
+ }
/// Terminal basic block (if any)
mlir::Block *finalBlock{};
HostAssociations hostAssociations;
diff --git a/flang/include/flang/Optimizer/Analysis/AliasAnalysis.h b/flang/include/flang/Optimizer/Analysis/AliasAnalysis.h
index a429c3c33bed4..c84451e9c6595 100644
--- a/flang/include/flang/Optimizer/Analysis/AliasAnalysis.h
+++ b/flang/include/flang/Optimizer/Analysis/AliasAnalysis.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <cstddef>
#include <memory>
#include <utility>
@@ -204,12 +205,13 @@ struct AliasAnalysis {
/// the same derived-type variable and tracks pointer dereferences for
/// pointer/target aliasing (Fortran 2018 8.5.7, 15.5.2.13).
struct AccessPath {
- llvm::SmallVector<PathStep, 4> steps;
+ llvm::SmallVectorWithFlags<PathStep, 4> steps;
/// Whether the path is approximate (e.g. contains array indexing or
/// went through PackArrayOp). An approximate path cannot yield
/// MustAlias.
- bool isApproximate{false};
+ bool isApproximate() const { return steps.getFlag(0); }
+ void setIsApproximate(bool value) { steps.setFlag(0, value); }
/// Return true if any step is a PointerDeref.
bool hasPointerDeref() const {
@@ -218,9 +220,7 @@ struct AliasAnalysis {
});
}
- bool operator==(const AccessPath &o) const {
- return isApproximate == o.isApproximate && steps == o.steps;
- }
+ bool operator==(const AccessPath &o) const { return steps == o.steps; }
bool operator!=(const AccessPath &o) const { return !(*this == o); }
void print(llvm::raw_ostream &os) const;
@@ -288,16 +288,34 @@ struct AliasAnalysis {
Attributes attributes;
/// Have we lost precision following the source such that
/// even an exact match cannot be MustAlias?
- bool approximateSource;
+ bool getApproximateSource() const { return scopedOrigins.getFlag(0); }
+ void setApproximateSource(bool Value) { scopedOrigins.setFlag(0, Value); }
/// The structured access path from the root variable.
AccessPath accessPath;
/// Source object is used in an internal procedure via host association.
- bool isCapturedInInternalProcedure{false};
+ bool getIsCapturedInInternalProcedure() const {
+ return scopedOrigins.getFlag(1);
+ }
+ void setIsCapturedInInternalProcedure(bool Value) {
+ scopedOrigins.setFlag(1, Value);
+ }
/// Per-declare checkpoints collected as getSource() walked through
/// [hl]fir.declare operations, ordered from leaf-closest (front) to
/// root-closest (back). Empty when no declare was crossed (e.g. the
/// walk terminated at Unknown).
- llvm::SmallVector<ScopedOrigin, 4> scopedOrigins;
+ llvm::SmallVectorWithFlags<ScopedOrigin, 4, 2> scopedOrigins;
+
+ Source() = default;
+ Source(SourceOrigin origin, SourceKind kind, mlir::Type valueType,
+ Attributes attributes, bool approximateSource,
+ AccessPath accessPath = {},
+ bool isCapturedInInternalProcedure = false,
+ llvm::SmallVector<ScopedOrigin, 4> scopedOrigins = {})
+ : origin(origin), kind(kind), valueType(valueType),
+ attributes(attributes), accessPath(std::move(accessPath)),
+ scopedOrigins(unsigned(approximateSource) |
+ (unsigned(isCapturedInInternalProcedure) << 1),
+ std::move(scopedOrigins)) {}
/// Print information about the memory source to `os`.
void print(llvm::raw_ostream &os) const;
@@ -581,11 +599,19 @@ class AliasAnalysisRecursiveEffectsCache {
};
struct Summary {
- bool hasUnknownWrite = false;
- bool hasUnknownRead = false;
+ bool getHasUnknownWrite() const { return calls.getFlag(0); }
+ bool setHasUnknownWrite(bool Value) {
+ calls.setFlag(0, Value);
+ return Value;
+ }
+ bool getHasUnknownRead() const { return calls.getFlag(1); }
+ bool setHasUnknownRead(bool Value) {
+ calls.setFlag(1, Value);
+ return Value;
+ }
llvm::SmallVector<mlir::Value, 16> writeLocations;
llvm::SmallVector<mlir::Value, 16> readLocations;
- llvm::SmallVector<CallInfo, 4> calls;
+ llvm::SmallVectorWithFlags<CallInfo, 4, 2> calls;
};
/// Populate `out` with the effects of `op` itself and, if op has
diff --git a/flang/include/flang/Optimizer/Builder/TemporaryStorage.h b/flang/include/flang/Optimizer/Builder/TemporaryStorage.h
index e1edc5912ae97..ca764d44fe564 100644
--- a/flang/include/flang/Optimizer/Builder/TemporaryStorage.h
+++ b/flang/include/flang/Optimizer/Builder/TemporaryStorage.h
@@ -21,6 +21,7 @@
#include "flang/Common/idioms.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace fir {
class FirOpBuilder;
@@ -122,9 +123,15 @@ class ArrayTemp {
bool canBeFetchedAfterPush() const { return true; }
private:
- const bool allocateOnHeap;
+ bool getAllocateOnHeap() const { return typeParams.getFlag(0); }
mlir::Value temp;
- llvm::SmallVector<mlir::Value> typeParams;
+ llvm::SmallVectorWithFlags<mlir::Value> typeParams;
+
+public:
+ ArrayTemp(const ArrayTemp &) = default;
+ ArrayTemp(ArrayTemp &&) = default;
+ ArrayTemp &operator=(const ArrayTemp &) = delete;
+ ArrayTemp &operator=(ArrayTemp &&) = delete;
};
/// Structure to hold the value of a single entity.
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index e52e690ab4b64..aef5fcddef6e7 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Lower/Bridge.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "flang/Evaluate/tools.h"
#include "flang/Lower/Allocatable.h"
@@ -101,7 +102,8 @@ struct IncrementLoopInfo {
: loopVariableSym{&sym}, lowerExpr{Fortran::semantics::GetExpr(lower)},
upperExpr{Fortran::semantics::GetExpr(upper)},
stepExpr{Fortran::semantics::GetExpr(step)},
- isConcurrent{isConcurrent} {}
+ sharedSymList(
+ decltype(this->sharedSymList)::withFlags(unsigned(isConcurrent))) {}
IncrementLoopInfo(IncrementLoopInfo &&) = default;
IncrementLoopInfo &operator=(IncrementLoopInfo &&x) = default;
@@ -124,19 +126,25 @@ struct IncrementLoopInfo {
const Fortran::lower::SomeExpr *upperExpr;
const Fortran::lower::SomeExpr *stepExpr;
const Fortran::lower::SomeExpr *maskExpr = nullptr;
- bool isConcurrent;
+ bool getIsConcurrent() const { return sharedSymList.getFlag(0); }
+ void setIsConcurrent(bool Value) { sharedSymList.setFlag(0, Value); }
llvm::SmallVector<const Fortran::semantics::Symbol *> localSymList;
llvm::SmallVector<const Fortran::semantics::Symbol *> localInitSymList;
llvm::SmallVector<const Fortran::semantics::Symbol *> reduceSymList;
llvm::SmallVector<fir::ReduceOperationEnum> reduceOperatorList;
- llvm::SmallVector<const Fortran::semantics::Symbol *> sharedSymList;
+ llvm::SmallVectorWithFlags<const Fortran::semantics::Symbol *,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ const Fortran::semantics::Symbol *>::value,
+ 2>
+ sharedSymList;
mlir::Value loopVariable = nullptr;
// Data members for structured loops.
mlir::Operation *loopOp = nullptr;
// Data members for unstructured loops.
- bool hasRealControl = false;
+ bool getHasRealControl() const { return sharedSymList.getFlag(1); }
+ void setHasRealControl(bool Value) { sharedSymList.setFlag(1, Value); }
mlir::Value tripVariable = nullptr;
mlir::Value stepVariable = nullptr;
mlir::Block *headerBlock = nullptr; // loop entry and test block
@@ -1845,7 +1853,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
getActiveAncestor(const Fortran::lower::pft::Evaluation &eval) {
Fortran::lower::pft::Evaluation *ancestor = eval.parentConstruct;
for (; ancestor; ancestor = ancestor->parentConstruct)
- if (ancestor->activeConstruct)
+ if (ancestor->getActiveConstruct())
break;
return ancestor;
}
@@ -2040,11 +2048,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
void pushActiveConstruct(Fortran::lower::pft::Evaluation &eval,
Fortran::lower::StatementContext &stmtCtx) {
activeConstructStack.push_back(ConstructContext{eval, stmtCtx});
- eval.activeConstruct = true;
+ eval.setActiveConstruct(true);
}
void popActiveConstruct() {
assert(!activeConstructStack.empty() && "invalid active construct stack");
- activeConstructStack.back().eval.activeConstruct = false;
+ activeConstructStack.back().eval.setActiveConstruct(false);
if (activeConstructStack.back().pushedScope)
localSymbols.popScope();
activeConstructStack.pop_back();
@@ -2952,8 +2960,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
if (unstructuredContext) {
maybeStartBlock(preheaderBlock);
maybeWrapAndRecalc();
- info.hasRealControl = info.loopVariableSym->GetType()->IsNumeric(
- Fortran::common::TypeCategory::Real);
+ info.setHasRealControl(info.loopVariableSym->GetType()->IsNumeric(
+ Fortran::common::TypeCategory::Real));
info.headerBlock = headerBlock;
info.bodyBlock = bodyBlock;
info.exitBlock = exitBlock;
@@ -2993,7 +3001,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// Introduce a `do concurrent` scope to bind symbols corresponding to local,
// local_init, and reduce region arguments.
if (!incrementLoopNestInfo.empty() &&
- incrementLoopNestInfo.back().isConcurrent)
+ incrementLoopNestInfo.back().getIsConcurrent())
localSymbols.pushScope();
// Increment loop begin code. (Infinite/while code was already generated.)
@@ -3031,7 +3039,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
attachAccessGroupAttrToDoLoopOperations(loopOp);
if (!incrementLoopNestInfo.empty() &&
- incrementLoopNestInfo.back().isConcurrent)
+ incrementLoopNestInfo.back().getIsConcurrent())
localSymbols.popScope();
// Add attribute(s) on operations in fir::DoLoopOp if necessary
@@ -3047,7 +3055,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
const IncrementLoopInfo &info,
bool *isConst = nullptr) {
mlir::Location loc = toLocation();
- mlir::Type controlType = info.isStructured() && info.isConcurrent
+ mlir::Type controlType = info.isStructured() && info.getIsConcurrent()
? builder->getIndexType()
: info.getLoopVariableType();
Fortran::lower::StatementContext stmtCtx;
@@ -3060,7 +3068,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
if (isConst)
*isConst = true;
- if (info.hasRealControl)
+ if (info.getHasRealControl())
return builder->createRealConstant(loc, controlType, 1u);
return builder->createIntegerConstant(loc, controlType, 1); // step
}
@@ -3096,11 +3104,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
bool genDoConcurrent = false;
for (IncrementLoopInfo &info : incrementLoopNestInfo) {
- genDoConcurrent = info.isStructured() && info.isConcurrent;
+ genDoConcurrent = info.isStructured() && info.getIsConcurrent();
if (!genDoConcurrent)
info.loopVariable = genLoopVariableAddress(loc, *info.loopVariableSym,
- info.isConcurrent);
+ info.getIsConcurrent());
if (!getLoweringOptions().getIntegerWrapAround()) {
iofBackup = builder->getIntegerOverflowFlags();
@@ -3150,7 +3158,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// Unstructured loop preheader - initialize tripVariable and loopVariable.
mlir::Value tripCount;
- if (info.hasRealControl) {
+ if (info.getHasRealControl()) {
auto diff1 =
mlir::arith::SubFOp::create(*builder, loc, upperValue, lowerValue);
auto diff2 =
@@ -3216,7 +3224,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
for (IncrementLoopInfo &info : llvm::reverse(incrementLoopNestInfo)) {
info.loopVariable = genLoopVariableAddress(loc, *info.loopVariableSym,
- info.isConcurrent);
+ info.getIsConcurrent());
}
builder->setInsertionPointToEnd(loopWrapperOp.getBody());
@@ -3279,7 +3287,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
IncrementLoopInfo &info = *it;
if (info.isStructured()) {
// End fir.do_concurent.loop.
- if (info.isConcurrent) {
+ if (info.getIsConcurrent()) {
builder->setInsertionPointAfter(info.loopOp->getParentOp());
continue;
}
@@ -3325,7 +3333,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
step = fir::LoadOp::create(*builder, loc, info.stepVariable);
else
step = genControlValue(info.stepExpr, info);
- if (info.hasRealControl)
+ if (info.getHasRealControl())
value = mlir::arith::AddFOp::create(*builder, loc, value, step);
else
value =
@@ -3358,9 +3366,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
};
setCurrentPosition(e.position);
if (auto *s = e.getIf<Fortran::parser::IfThenStmt>()) {
- topIfOp = currentIfOp = genIfOp(genIfCondition(s, e.negateCondition));
+ topIfOp = currentIfOp =
+ genIfOp(genIfCondition(s, e.getNegateCondition()));
} else if (auto *s = e.getIf<Fortran::parser::IfStmt>()) {
- topIfOp = currentIfOp = genIfOp(genIfCondition(s, e.negateCondition));
+ topIfOp = currentIfOp =
+ genIfOp(genIfCondition(s, e.getNegateCondition()));
} else if (auto *s = e.getIf<Fortran::parser::ElseIfStmt>()) {
builder->setInsertionPointToStart(
¤tIfOp.getElseRegion().front());
@@ -3420,10 +3430,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
setCurrentPosition(e.position);
if (auto *s = e.getIf<Fortran::parser::IfThenStmt>()) {
maybeStartBlock(e.block);
- genIfBranch(genIfCondition(s, e.negateCondition));
+ genIfBranch(genIfCondition(s, e.getNegateCondition()));
} else if (auto *s = e.getIf<Fortran::parser::IfStmt>()) {
maybeStartBlock(e.block);
- genIfBranch(genIfCondition(s, e.negateCondition));
+ genIfBranch(genIfCondition(s, e.getNegateCondition()));
} else if (auto *s = e.getIf<Fortran::parser::ElseIfStmt>()) {
startBlock(e.block);
genIfBranch(genIfCondition(s));
@@ -4369,8 +4379,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
builder->restoreInsertionPoint(insertPt);
// Register if a target region was found
- ompDeviceCodeFound =
- ompDeviceCodeFound || Fortran::lower::isOpenMPTargetConstruct(omp);
+ setOmpDeviceCodeFound(getOmpDeviceCodeFound() ||
+ Fortran::lower::isOpenMPTargetConstruct(omp));
}
void genFIR(const Fortran::parser::OpenMPDeclarativeConstruct &ompDecl) {
@@ -4378,10 +4388,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint();
// Register if a declare target construct intended for a target device was
// found
- ompDeviceCodeFound =
- ompDeviceCodeFound ||
+ setOmpDeviceCodeFound(
+ getOmpDeviceCodeFound() ||
Fortran::lower::isOpenMPDeviceDeclareTarget(
- *this, bridge.getSemanticsContext(), getEval(), ompDecl);
+ *this, bridge.getSemanticsContext(), getEval(), ompDecl));
Fortran::lower::gatherOpenMPDeferredDeclareTargets(
*this, bridge.getSemanticsContext(), getEval(), ompDecl,
ompDeferredDeclareTarget);
@@ -6318,8 +6328,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
? eval.getFirstNestedEvaluation().block
: eval.block);
- if (eval.skipNextLowering) {
- eval.skipNextLowering = false;
+ if (eval.getSkipNextLowering()) {
+ eval.setSkipNextLowering(false);
return;
}
@@ -6418,7 +6428,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
mlir::Location loc = toLocation();
mlir::Location endLoc =
toLocation(Fortran::lower::pft::stmtSourceLoc(funit.endStmt));
- if (funit.hasIeeeAccess) {
+ if (funit.getHasIeeeAccess()) {
// Subject to F18 Clause 17.1p3, 17.3p3 states: If a flag is signaling
// on entry to a procedure [...], the processor will set it to quiet
// on entry and restore it to signaling on return. If a flag signals
@@ -6436,7 +6446,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
fir::CallOp::create(*builder, endLoc, raiseExcept, exceptSet);
});
}
- if (funit.mayModifyHaltingMode) {
+ if (funit.getMayModifyHaltingMode()) {
// F18 Clause 17.6p1: In a procedure [...], the processor shall not
// change the halting mode on entry, and on return shall ensure that
// the halting mode is the same as it was on entry.
@@ -6454,7 +6464,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
fir::CallOp::create(*builder, endLoc, enableExcept, exceptSet);
});
}
- if (funit.mayModifyRoundingMode) {
+ if (funit.getMayModifyRoundingMode()) {
// F18 Clause 17.4p5: In a procedure [...], the processor shall not
// change the rounding modes on entry, and on return shall ensure that
// the rounding modes are the same as they were on entry.
@@ -6468,7 +6478,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
fir::CallOp::create(*builder, endLoc, setRounding, roundingMode);
});
}
- if ((funit.mayModifyUnderflowMode) &&
+ if ((funit.getMayModifyUnderflowMode()) &&
(bridge.getTargetCharacteristics().hasSubnormalFlushingControl(
/*any=*/true))) {
// F18 Clause 17.5p2: In a procedure [...], the processor shall not
@@ -6718,7 +6728,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
evaluationList) {
mlir::Region *region = &builder->getRegion();
for (Fortran::lower::pft::Evaluation &eval : evaluationList) {
- if (eval.isNewBlock)
+ if (eval.getIsNewBlock())
eval.block = builder->createBlock(region);
if (eval.isConstruct() || eval.isDirective()) {
if (Fortran::lower::pft::isWrappableConstruct(
@@ -6728,7 +6738,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
if (eval.hasNestedEvaluations()) {
Fortran::lower::pft::Evaluation &constructStmt =
eval.getFirstNestedEvaluation();
- if (constructStmt.isNewBlock)
+ if (constructStmt.getIsNewBlock())
constructStmt.block = builder->createBlock(region);
}
} else if (eval.lowerAsUnstructured()) {
@@ -6737,7 +6747,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// A structured construct that is a target starts a new block.
Fortran::lower::pft::Evaluation &constructStmt =
eval.getFirstNestedEvaluation();
- if (constructStmt.isNewBlock)
+ if (constructStmt.getIsNewBlock())
constructStmt.block = builder->createBlock(region);
}
}
@@ -7126,11 +7136,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
bool deferredDeviceFuncFound =
Fortran::lower::markOpenMPDeferredDeclareTargetFunctions(
getModuleOp().getOperation(), ompDeferredDeclareTarget, *this);
- ompDeviceCodeFound = ompDeviceCodeFound || deferredDeviceFuncFound;
+ setOmpDeviceCodeFound(getOmpDeviceCodeFound() || deferredDeviceFuncFound);
}
// Set the module attribute related to OpenMP requires directives
- if (ompDeviceCodeFound) {
+ if (getOmpDeviceCodeFound()) {
for (const Fortran::semantics::Symbol *sym : globalOmpRequiresSymbol)
Fortran::lower::genOpenMPRequires(getModuleOp().getOperation(), sym);
}
@@ -7229,7 +7239,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
llvm::DenseMap<const Fortran::lower::SomeExpr *, std::string> literalNamesMap;
/// Storage for Constant expressions used as keys for literalNamesMap.
- llvm::SmallVector<std::unique_ptr<Fortran::lower::SomeExpr>>
+ llvm::SmallVectorWithFlags<std::unique_ptr<Fortran::lower::SomeExpr>>
literalExprsStorage;
/// A counter for uniquing names in `literalNamesMap`.
@@ -7237,7 +7247,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
/// Whether an OpenMP target region or declare target function/subroutine
/// intended for device offloading has been detected
- bool ompDeviceCodeFound = false;
+ bool getOmpDeviceCodeFound() const { return literalExprsStorage.getFlag(0); }
+ void setOmpDeviceCodeFound(bool Value) {
+ literalExprsStorage.setFlag(0, Value);
+ }
/// Keeps track of symbols defined as declare target that could not be
/// processed at the time of lowering the declare target construct, such
diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp
index ee6ee38f165f9..09d4706695da8 100644
--- a/flang/lib/Lower/CallInterface.cpp
+++ b/flang/lib/Lower/CallInterface.cpp
@@ -570,7 +570,7 @@ Fortran::lower::CallerInterface::getDummySymbol(
mlir::Type Fortran::lower::CallerInterface::getResultStorageType() const {
if (passedResult)
return fir::dyn_cast_ptrEleTy(inputs[passedResult->firArgument].type);
- assert(saveResult && !outputs.empty());
+ assert(mustSaveResult() && !outputs.empty());
return outputs[0].type;
}
@@ -1484,7 +1484,7 @@ class Fortran::lower::CallInterfaceImpl {
interface.passedResult =
PassedEntity{p, entity, emptyValue(), emptyValue()};
}
- void setSaveResult() { interface.saveResult = true; }
+ void setSaveResult() { interface.passedArguments.setFlag(0, true); }
int nextPassedArgPosition() { return interface.passedArguments.size(); }
static FirValue emptyValue() {
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index b1f29bb23361f..4f03e7beda399 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -12,6 +12,7 @@
#include "ClauseProcessor.h"
#include "Utils.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "flang/Lower/ConvertCall.h"
#include "flang/Lower/ConvertExprToHLFIR.h"
@@ -1230,34 +1231,39 @@ class TypeInfo {
llvm::ArrayRef<int64_t> getShape() const { return shape; }
// Is the type inside a box?
- bool isBox() const { return inBox; }
+ bool isBox() const { return getInBox(); }
- bool isBoxChar() const { return inBoxChar; }
+ bool isBoxChar() const { return getInBoxChar(); }
private:
void typeScan(mlir::Type type);
std::optional<fir::CharacterType::LenType> charLen;
- llvm::SmallVector<int64_t> shape;
- bool inBox = false;
- bool inBoxChar = false;
+ llvm::SmallVectorWithFlags<
+ int64_t, llvm::CalculateSmallVectorDefaultInlinedElements<int64_t>::value,
+ 2>
+ shape;
+ bool getInBox() const { return shape.getFlag(0); }
+ void setInBox(bool Value) { shape.setFlag(0, Value); }
+ bool getInBoxChar() const { return shape.getFlag(1); }
+ void setInBoxChar(bool Value) { shape.setFlag(1, Value); }
};
void TypeInfo::typeScan(mlir::Type ty) {
if (auto sty = mlir::dyn_cast<fir::SequenceType>(ty)) {
assert(shape.empty() && !sty.getShape().empty());
- shape = llvm::SmallVector<int64_t>(sty.getShape());
+ shape.assign(llvm::SmallVector<int64_t>(sty.getShape()));
typeScan(sty.getEleTy());
} else if (auto bty = mlir::dyn_cast<fir::BoxType>(ty)) {
- inBox = true;
+ setInBox(true);
typeScan(bty.getEleTy());
} else if (auto cty = mlir::dyn_cast<fir::ClassType>(ty)) {
- inBox = true;
+ setInBox(true);
typeScan(cty.getEleTy());
} else if (auto cty = mlir::dyn_cast<fir::CharacterType>(ty)) {
charLen = cty.getLen();
} else if (auto cty = mlir::dyn_cast<fir::BoxCharType>(ty)) {
- inBoxChar = true;
+ setInBoxChar(true);
typeScan(cty.getEleTy());
} else if (auto hty = mlir::dyn_cast<fir::HeapType>(ty)) {
typeScan(hty.getEleTy());
@@ -1271,7 +1277,7 @@ void TypeInfo::typeScan(mlir::Type ty) {
assert(ty.isIntOrIndexOrFloat() || mlir::isa<mlir::ComplexType>(ty) ||
mlir::isa<fir::LogicalType>(ty) || mlir::isa<fir::RecordType>(ty) ||
mlir::isa<fir::BoxProcType>(ty) ||
- (inBox && mlir::isa<mlir::NoneType>(ty)));
+ (getInBox() && mlir::isa<mlir::NoneType>(ty)));
}
}
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
index 98561803ea8bb..89db551a9ce8c 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
@@ -72,11 +72,12 @@ DataSharingProcessor::DataSharingProcessor(
bool shouldCollectPreDeterminedSymbols, bool useDelayedPrivatization,
lower::SymMap &symTable, bool isTargetPrivatization,
llvm::ArrayRef<const semantics::Symbol *> metadirectiveLoopIVs)
- : converter(converter), semaCtx(semaCtx),
+ : loopIVs(decltype(this->loopIVs)::withFlags(
+ (unsigned(shouldCollectPreDeterminedSymbols) << 1) |
+ (unsigned(useDelayedPrivatization) << 2))),
+ converter(converter), semaCtx(semaCtx),
firOpBuilder(converter.getFirOpBuilder()), clauses(clauses), eval(eval),
- shouldCollectPreDeterminedSymbols(shouldCollectPreDeterminedSymbols),
- useDelayedPrivatization(useDelayedPrivatization), symTable(symTable),
- isTargetPrivatization(isTargetPrivatization),
+ symTable(symTable), isTargetPrivatization(isTargetPrivatization),
isMetadirectiveLoop(!metadirectiveLoopIVs.empty()) {}
DataSharingProcessor::DataSharingProcessor(lower::AbstractConverter &converter,
@@ -128,7 +129,7 @@ void DataSharingProcessor::processStep2(mlir::Operation *op, bool isLoop) {
void DataSharingProcessor::insertDeallocs() {
for (const semantics::Symbol *sym : allPrivatizedSymbols)
if (semantics::IsAllocatable(sym->GetUltimate())) {
- if (!useDelayedPrivatization) {
+ if (!getUseDelayedPrivatization()) {
converter.createHostAssociateVarCloneDealloc(*sym);
continue;
}
@@ -336,10 +337,10 @@ void DataSharingProcessor::collectSymbolsForPrivatization() {
// standard lastprivate copy-back suppressed (see copyLastPrivateSymbol /
// insertLastPrivateCompare) in favor of the conditional copy-back.
for (auto *sym : explicitlyPrivatizedSymbols)
- if (!isException(sym) && (conditionalLpUsesPrivateCopy ||
+ if (!isException(sym) && (getConditionalLpUsesPrivateCopyFlag() ||
!conditionalLastPrivatizedSymbols.contains(sym)))
allPrivatizedSymbols.insert(sym);
- if (conditionalLpUsesPrivateCopy)
+ if (getConditionalLpUsesPrivateCopyFlag())
for (auto *sym : conditionalLastPrivatizedSymbols)
if (!isException(sym))
allPrivatizedSymbols.insert(sym);
@@ -373,7 +374,7 @@ void DataSharingProcessor::insertBarrier(
if (!needBarrier())
return;
- if (useDelayedPrivatization) {
+ if (getUseDelayedPrivatization()) {
if (clauseOps)
clauseOps->privateNeedsBarrier =
mlir::UnitAttr::get(&converter.getMLIRContext());
@@ -655,7 +656,7 @@ void DataSharingProcessor::collectImplicitSymbols() {
}
void DataSharingProcessor::collectPreDeterminedSymbols() {
- if (shouldCollectPreDeterminedSymbols)
+ if (getShouldCollectPreDeterminedSymbols())
collectSymbols(semantics::Symbol::Flag::OmpPreDetermined);
}
@@ -664,7 +665,7 @@ void DataSharingProcessor::collectPreDeterminedSymbols() {
// enclosing context, to avoid updating the wrong symbol.
void DataSharingProcessor::collectIndirectReferences() {
// For compound constructs, collect the symbols only for the last leaf.
- if (!shouldCollectPreDeterminedSymbols)
+ if (!getShouldCollectPreDeterminedSymbols())
return;
const semantics::Scope *curScope = getCurrentScope(semaCtx, eval);
@@ -749,7 +750,7 @@ void DataSharingProcessor::privatizeSymbol(
const semantics::Symbol *symToPrivatize,
mlir::omp::PrivateClauseOps *clauseOps,
std::optional<llvm::omp::Directive> dir) {
- if (!useDelayedPrivatization) {
+ if (!getUseDelayedPrivatization()) {
cloneSymbol(symToPrivatize);
copyFirstPrivateSymbol(symToPrivatize);
return;
@@ -759,7 +760,7 @@ void DataSharingProcessor::privatizeSymbol(
mlir::omp::PrivateClauseOps>(
converter, firOpBuilder, symTable, allPrivatizedSymbols,
mightHaveReadHostSym, symToPrivatize, clauseOps, dir,
- forceHeapAllocationForPrivateDynamicArrays);
+ getForceHeapAllocationForPrivateDynamicArraysFlag());
}
} // namespace omp
} // namespace lower
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.h b/flang/lib/Lower/OpenMP/DataSharingProcessor.h
index 73044c304800b..276063867da2e 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.h
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.h
@@ -19,6 +19,7 @@
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/symbol.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <variant>
namespace mlir {
@@ -34,7 +35,10 @@ namespace omp {
class DataSharingProcessor {
private:
mlir::OpBuilder::InsertPoint lastPrivIP;
- llvm::SmallVector<mlir::Value> loopIVs;
+ llvm::SmallVectorWithFlags<
+ mlir::Value,
+ llvm::CalculateSmallVectorDefaultInlinedElements<mlir::Value>::value, 4>
+ loopIVs;
// Symbols in private, firstprivate, and/or lastprivate clauses.
llvm::SetVector<const semantics::Symbol *> explicitlyPrivatizedSymbols;
llvm::SetVector<const semantics::Symbol *> defaultSymbols;
@@ -46,16 +50,32 @@ class DataSharingProcessor {
// nonmonotonic schedule can execute chunks out of order. When false the list
// item is bound directly to the reduction struct (used by sections, which are
// lexically ordered and never need the private copy).
- bool conditionalLpUsesPrivateCopy = false;
+ bool getConditionalLpUsesPrivateCopyFlag() const {
+ return loopIVs.getFlag(0);
+ }
+ void setConditionalLpUsesPrivateCopyFlag(bool Value) {
+ loopIVs.setFlag(0, Value);
+ }
lower::AbstractConverter &converter;
semantics::SemanticsContext &semaCtx;
fir::FirOpBuilder &firOpBuilder;
omp::List<omp::Clause> clauses;
lower::pft::Evaluation &eval;
- bool shouldCollectPreDeterminedSymbols;
- bool useDelayedPrivatization;
- bool forceHeapAllocationForPrivateDynamicArrays = false;
+ bool getShouldCollectPreDeterminedSymbols() const {
+ return loopIVs.getFlag(1);
+ }
+ void setShouldCollectPreDeterminedSymbols(bool Value) {
+ loopIVs.setFlag(1, Value);
+ }
+ bool getUseDelayedPrivatization() const { return loopIVs.getFlag(2); }
+ void setUseDelayedPrivatization(bool Value) { loopIVs.setFlag(2, Value); }
+ bool getForceHeapAllocationForPrivateDynamicArraysFlag() const {
+ return loopIVs.getFlag(3);
+ }
+ void setForceHeapAllocationForPrivateDynamicArraysFlag(bool Value) {
+ loopIVs.setFlag(3, Value);
+ }
llvm::SmallPtrSet<const semantics::Symbol *, 16> mightHaveReadHostSym;
lower::SymMap &symTable;
bool isTargetPrivatization;
@@ -130,7 +150,7 @@ class DataSharingProcessor {
void pushLoopIV(mlir::Value iv) { loopIVs.push_back(iv); }
void setForceHeapAllocationForPrivateDynamicArrays(bool value = true) {
- forceHeapAllocationForPrivateDynamicArrays = value;
+ setForceHeapAllocationForPrivateDynamicArraysFlag(value);
}
const llvm::SetVector<const semantics::Symbol *> &
@@ -139,7 +159,7 @@ class DataSharingProcessor {
}
llvm::ArrayRef<const semantics::Symbol *> getDelayedPrivSymbols() const {
- return useDelayedPrivatization
+ return getUseDelayedPrivatization()
? allPrivatizedSymbols.getArrayRef()
: llvm::ArrayRef<const semantics::Symbol *>();
}
@@ -154,7 +174,7 @@ class DataSharingProcessor {
}
void setConditionalLpUsesPrivateCopy(bool v) {
- conditionalLpUsesPrivateCopy = v;
+ setConditionalLpUsesPrivateCopyFlag(v);
}
};
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 57978826c5d01..e674c0c3559be 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Lower/OpenMP.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "Atomic.h"
#include "ClauseProcessor.h"
@@ -334,17 +335,17 @@ class HostEvalInfo {
/// evaluated in the host device.
bool apply(mlir::omp::LoopNestOperands &clauseOps,
llvm::SmallVectorImpl<const semantics::Symbol *> &ivOut) {
- if (iv.empty() || loopNestApplied) {
- loopNestApplied = true;
+ if (iv.empty() || getLoopNestApplied()) {
+ setLoopNestApplied(true);
return false;
}
- loopNestApplied = true;
+ setLoopNestApplied(true);
clauseOps.loopLowerBounds = ops.loopLowerBounds;
clauseOps.loopUpperBounds = ops.loopUpperBounds;
clauseOps.loopSteps = ops.loopSteps;
clauseOps.collapseNumLoops = ops.collapseNumLoops;
- ivOut.append(iv);
+ ivOut.append(iv.begin(), iv.end());
return true;
}
@@ -354,12 +355,12 @@ class HostEvalInfo {
/// \returns whether an update was performed. If not, these clauses were not
/// evaluated in the host device.
bool apply(mlir::omp::ParallelOperands &clauseOps) {
- if (ops.numThreadsVars.empty() || parallelApplied) {
- parallelApplied = true;
+ if (ops.numThreadsVars.empty() || getParallelApplied()) {
+ setParallelApplied(true);
return false;
}
- parallelApplied = true;
+ setParallelApplied(true);
clauseOps.numThreadsVars = ops.numThreadsVars;
return true;
}
@@ -382,8 +383,15 @@ class HostEvalInfo {
private:
mlir::omp::HostEvaluatedOperands ops;
- llvm::SmallVector<const semantics::Symbol *> iv;
- bool loopNestApplied = false, parallelApplied = false;
+ llvm::SmallVectorWithFlags<const semantics::Symbol *,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ const semantics::Symbol *>::value,
+ 2>
+ iv;
+ bool getLoopNestApplied() const { return iv.getFlag(0); }
+ void setLoopNestApplied(bool Value) { iv.setFlag(0, Value); }
+ bool getParallelApplied() const { return iv.getFlag(1); }
+ void setParallelApplied(bool Value) { iv.setFlag(1, Value); }
};
/// A base class to help iterate over OpenMP constructs based on an expected
@@ -629,10 +637,14 @@ class HostEvalVisitor : public TargetSPMDVisitor {
case OMPD_distribute:
case OMPD_distribute_simd:
case OMPD_do:
- case OMPD_do_simd:
+ case OMPD_do_simd: {
+ llvm::SmallVector<const semantics::Symbol *> InductionVariables;
+ InductionVariables = std::move(hostEvalInfo.iv);
cp.processCollapse(loc, eval, hostEvalInfo.ops, hostEvalInfo.ops,
- hostEvalInfo.iv);
+ InductionVariables);
+ hostEvalInfo.iv.assign(std::move(InductionVariables));
return {};
+ }
case OMPD_teams:
cp.processThreadLimit(stmtCtx, hostEvalInfo.ops);
@@ -646,11 +658,15 @@ class HostEvalVisitor : public TargetSPMDVisitor {
cp.processThreadLimit(stmtCtx, hostEvalInfo.ops);
[[fallthrough]];
case OMPD_target_teams_distribute:
- case OMPD_target_teams_distribute_simd:
+ case OMPD_target_teams_distribute_simd: {
+ llvm::SmallVector<const semantics::Symbol *> InductionVariables;
+ InductionVariables = std::move(hostEvalInfo.iv);
cp.processCollapse(loc, eval, hostEvalInfo.ops, hostEvalInfo.ops,
- hostEvalInfo.iv);
+ InductionVariables);
+ hostEvalInfo.iv.assign(std::move(InductionVariables));
cp.processNumTeams(stmtCtx, hostEvalInfo.ops);
return {};
+ }
case OMPD_teams_loop:
cp.processThreadLimit(stmtCtx, hostEvalInfo.ops);
@@ -658,10 +674,14 @@ class HostEvalVisitor : public TargetSPMDVisitor {
case OMPD_target_teams_loop:
cp.processNumTeams(stmtCtx, hostEvalInfo.ops);
[[fallthrough]];
- case OMPD_loop:
+ case OMPD_loop: {
+ llvm::SmallVector<const semantics::Symbol *> InductionVariables;
+ InductionVariables = std::move(hostEvalInfo.iv);
cp.processCollapse(loc, eval, hostEvalInfo.ops, hostEvalInfo.ops,
- hostEvalInfo.iv);
+ InductionVariables);
+ hostEvalInfo.iv.assign(std::move(InductionVariables));
return {};
+ }
case OMPD_teams_workdistribute:
cp.processThreadLimit(stmtCtx, hostEvalInfo.ops);
@@ -7058,23 +7078,23 @@ struct SplicedAssociatedEvaluations {
// A saved successor may also have been spliced. Restore in reverse order
// so every insertion point is back in the parent list before it is used.
for (auto &entry : llvm::reverse(evaluations)) {
- entry.first->skipNextLowering = true;
+ entry.first->setSkipNextLowering(true);
parentList->splice(entry.second, nested, entry.first);
}
if (entryEvaluation) {
- entryEvaluation->isNewBlock = true;
+ entryEvaluation->setIsNewBlock(true);
entryEvaluation->block = entryBlock;
}
}
void suppressEntryBlock(lower::pft::Evaluation &evaluation) {
- assert(!entryEvaluation && evaluation.isNewBlock && evaluation.block &&
+ assert(!entryEvaluation && evaluation.getIsNewBlock() && evaluation.block &&
"invalid associated entry evaluation");
// Do not let either cloned loop arm enter a function-region block. The
// metadirective selection will be placed in this block for an active ENTRY.
entryEvaluation = &evaluation;
entryBlock = evaluation.block;
- evaluation.isNewBlock = false;
+ evaluation.setIsNewBlock(false);
evaluation.block = nullptr;
}
@@ -7199,13 +7219,13 @@ static lower::pft::Evaluation *spliceAssociatedDoEval(
auto entryIt =
llvm::find_if(llvm::make_range(firstAssociatedIt, loopIt),
[](lower::pft::Evaluation &candidate) {
- return candidate.isNewBlock && candidate.block;
+ return candidate.getIsNewBlock() && candidate.block;
});
if (entryIt != loopIt) {
splicedEvaluations->suppressEntryBlock(*entryIt);
} else {
lower::pft::Evaluation &doStmt = loopIt->getFirstNestedEvaluation();
- if (doStmt.isNewBlock && doStmt.block)
+ if (doStmt.getIsNewBlock() && doStmt.block)
splicedEvaluations->suppressEntryBlock(doStmt);
}
}
diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index 536ba708b1916..09975768f8644 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -177,19 +177,19 @@ class PFTBuilder {
return;
lower::pft::FunctionLikeUnit *proc =
evaluationListStack.back()->back().getOwningProcedure();
- proc->hasIeeeAccess = true;
+ proc->setHasIeeeAccess(true);
if (!procName.starts_with("ieee_set_"))
return;
if (procName.starts_with("ieee_set_modes_") ||
procName.starts_with("ieee_set_status_"))
- proc->mayModifyHaltingMode = proc->mayModifyRoundingMode =
- proc->mayModifyUnderflowMode = true;
+ proc->setMayModifyHaltingMode(proc->setMayModifyRoundingMode(
+ proc->setMayModifyUnderflowMode(true)));
else if (procName.starts_with("ieee_set_halting_mode_"))
- proc->mayModifyHaltingMode = true;
+ proc->setMayModifyHaltingMode(true);
else if (procName.starts_with("ieee_set_rounding_mode_"))
- proc->mayModifyRoundingMode = true;
+ proc->setMayModifyRoundingMode(true);
else if (procName.starts_with("ieee_set_underflow_mode_"))
- proc->mayModifyUnderflowMode = true;
+ proc->setMayModifyUnderflowMode(true);
}
/// Convert an IfStmt into an IfConstruct, retaining the IfStmt as the
@@ -860,7 +860,7 @@ class PFTBuilder {
"expected goto or cycle statement");
ifBodyList.erase(branchStmtIt);
lower::pft::Evaluation &ifStmt = *ifBodyList.begin();
- ifStmt.negateCondition = true;
+ ifStmt.setNegateCondition(true);
ifStmt.lexicalSuccessor = firstStmt(&*successorIt);
lower::pft::EvaluationList::iterator endIfStmtIt =
std::prev(ifBodyList.end());
@@ -962,7 +962,7 @@ class PFTBuilder {
sourceEvaluation.extraControlSuccessors.push_back(&targetEvaluation);
// Record the reverse edge beside the forward one.
(*incomingBranches)[&targetEvaluation].insert(&sourceEvaluation);
- targetEvaluation.isNewBlock = true;
+ targetEvaluation.setIsNewBlock(true);
// If this is a branch into the body of a construct (usually illegal,
// but allowed in some legacy cases), then the targetEvaluation and its
// ancestors must be marked as unstructured.
@@ -985,7 +985,7 @@ class PFTBuilder {
// this to be done when the construct is analyzed.
if (eval->constructExit && (eval->isA<parser::DoConstruct>() ||
eval->isA<parser::IfConstruct>()))
- eval->constructExit->isNewBlock = true;
+ eval->constructExit->setIsNewBlock(true);
}
}
}
@@ -1000,7 +1000,7 @@ class PFTBuilder {
/// Mark the successor of an Evaluation as a new block.
void markSuccessorAsNewBlock(lower::pft::Evaluation &eval) {
- eval.nonNopSuccessor().isNewBlock = true;
+ eval.nonNopSuccessor().setIsNewBlock(true);
}
template <typename A>
@@ -1093,7 +1093,7 @@ class PFTBuilder {
},
[&](const parser::GotoStmt &s) { markBranchTarget(eval, s.v); },
[&](const parser::IfStmt &) {
- eval.lexicalSuccessor->isNewBlock = true;
+ eval.lexicalSuccessor->setIsNewBlock(true);
lastConstructStmtEvaluation = &eval;
},
[&](const parser::ReturnStmt &) {
@@ -1127,7 +1127,7 @@ class PFTBuilder {
// Consult the same classification the assigned GO TO uses, so the
// two agree on which statements may be branched to.
if (semanticsContext.IsRecordedBranchTarget(target->position)) {
- target->isNewBlock = true;
+ target->setIsNewBlock(true);
for (lower::pft::Evaluation *parent = target->parentConstruct;
parent; parent = parent->parentConstruct) {
parent->markUnstructured();
@@ -1135,7 +1135,7 @@ class PFTBuilder {
if (parent->constructExit &&
(parent->isA<parser::DoConstruct>() ||
parent->isA<parser::IfConstruct>()))
- parent->constructExit->isNewBlock = true;
+ parent->constructExit->setIsNewBlock(true);
}
}
},
@@ -1174,7 +1174,7 @@ class PFTBuilder {
// The first executable statement after an EntryStmt is a new block.
[&](const parser::EntryStmt &) {
- eval.lexicalSuccessor->isNewBlock = true;
+ eval.lexicalSuccessor->setIsNewBlock(true);
},
// Construct statements
@@ -1189,12 +1189,12 @@ class PFTBuilder {
lastConstructStmtEvaluation = &eval;
},
[&](const parser::CaseStmt &) {
- eval.isNewBlock = true;
+ eval.setIsNewBlock(true);
lastConstructStmtEvaluation->controlSuccessor = &eval;
lastConstructStmtEvaluation = &eval;
},
[&](const parser::EndSelectStmt &) {
- eval.isNewBlock = true;
+ eval.setIsNewBlock(true);
lastConstructStmtEvaluation = nullptr;
},
[&](const parser::ChangeTeamStmt &s) {
@@ -1212,7 +1212,7 @@ class PFTBuilder {
eval.markUnstructured(); // infinite loop
return;
}
- eval.nonNopSuccessor().isNewBlock = true;
+ eval.nonNopSuccessor().setIsNewBlock(true);
eval.controlSuccessor = &evaluationList.back();
if (const auto *bounds =
std::get_if<parser::LoopControl::Bounds>(&loopControl->u)) {
@@ -1235,7 +1235,7 @@ class PFTBuilder {
return;
// The loop is unstructured, which wasn't known for all cases when
// visiting the NonLabelDoStmt.
- parentConstruct->constructExit->isNewBlock = true;
+ parentConstruct->constructExit->setIsNewBlock(true);
const auto &doStmt = *doEval.getIf<parser::NonLabelDoStmt>();
const auto &loopControl =
std::get<std::optional<parser::LoopControl>>(doStmt.t);
@@ -1247,30 +1247,34 @@ class PFTBuilder {
// If there is a mask, the EndDoStmt starts a new block.
const auto &header =
std::get<parser::ConcurrentHeader>(concurrent->t);
- eval.isNewBlock |=
- std::get<std::optional<parser::ScalarLogicalExpr>>(header.t)
- .has_value();
+ [&] {
+ auto PackedFlagValue =
+ std::get<std::optional<parser::ScalarLogicalExpr>>(header.t)
+ .has_value();
+ return eval.setIsNewBlock(eval.getIsNewBlock() |
+ PackedFlagValue);
+ }();
}
},
[&](const parser::IfThenStmt &s) {
insertConstructName(s, parentConstruct);
- eval.lexicalSuccessor->isNewBlock = true;
+ eval.lexicalSuccessor->setIsNewBlock(true);
lastConstructStmtEvaluation = &eval;
},
[&](const parser::ElseIfStmt &) {
- eval.isNewBlock = true;
- eval.lexicalSuccessor->isNewBlock = true;
+ eval.setIsNewBlock(true);
+ eval.lexicalSuccessor->setIsNewBlock(true);
lastConstructStmtEvaluation->controlSuccessor = &eval;
lastConstructStmtEvaluation = &eval;
},
[&](const parser::ElseStmt &) {
- eval.isNewBlock = true;
+ eval.setIsNewBlock(true);
lastConstructStmtEvaluation->controlSuccessor = &eval;
lastConstructStmtEvaluation = nullptr;
},
[&](const parser::EndIfStmt &) {
if (parentConstruct->lowerAsUnstructured())
- parentConstruct->constructExit->isNewBlock = true;
+ parentConstruct->constructExit->setIsNewBlock(true);
if (lastConstructStmtEvaluation) {
lastConstructStmtEvaluation->controlSuccessor =
parentConstruct->constructExit;
@@ -1282,7 +1286,7 @@ class PFTBuilder {
lastConstructStmtEvaluation = &eval;
},
[&](const parser::SelectRankCaseStmt &) {
- eval.isNewBlock = true;
+ eval.setIsNewBlock(true);
lastConstructStmtEvaluation->controlSuccessor = &eval;
lastConstructStmtEvaluation = &eval;
},
@@ -1291,7 +1295,7 @@ class PFTBuilder {
lastConstructStmtEvaluation = &eval;
},
[&](const parser::TypeGuardStmt &) {
- eval.isNewBlock = true;
+ eval.setIsNewBlock(true);
lastConstructStmtEvaluation->controlSuccessor = &eval;
lastConstructStmtEvaluation = &eval;
},
@@ -1373,7 +1377,7 @@ class PFTBuilder {
initialEval = &initialEval->getFirstNestedEvaluation();
else if (initialEval->isA<Fortran::parser::EntryStmt>())
initialEval = initialEval->lexicalSuccessor;
- initialEval->isNewBlock = true;
+ initialEval->setIsNewBlock(true);
// All function entry points share a single result container.
// Find one of the largest results.
@@ -1499,7 +1503,7 @@ class PFTDumper {
const lower::pft::Evaluation &eval,
const std::string &indentString, int indent = 1) {
llvm::StringRef name = evaluationName(eval);
- llvm::StringRef newBlock = eval.isNewBlock ? "^" : "";
+ llvm::StringRef newBlock = eval.getIsNewBlock() ? "^" : "";
// "!" marks an unstructured evaluation. "~" marks one that is structured
// on the outside but has unstructured internals.
llvm::StringRef bang = eval.hasUnstructuredInternals()
@@ -1512,7 +1516,7 @@ class PFTDumper {
outputStream << "<<" << newBlock << name << bang << ">>";
else
outputStream << newBlock << name << bang;
- if (eval.negateCondition)
+ if (eval.getNegateCondition())
outputStream << " [negate]";
if (eval.constructExit) {
outputStream << " -> " << eval.constructExit->printIndex;
diff --git a/flang/lib/Lower/Support/PrivateReductionUtils.cpp b/flang/lib/Lower/Support/PrivateReductionUtils.cpp
index 8008730ba065f..3d69bf227086d 100644
--- a/flang/lib/Lower/Support/PrivateReductionUtils.cpp
+++ b/flang/lib/Lower/Support/PrivateReductionUtils.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Lower/Support/PrivateReductionUtils.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "flang/Lower/AbstractConverter.h"
#include "flang/Lower/Allocatable.h"
@@ -257,17 +258,18 @@ static void initializeIfDerivedTypeBox(fir::FirOpBuilder &builder,
fir::runtime::genDerivedTypeInitializeClone(builder, loc, newBox, moldBox);
}
-static void getLengthParameters(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::Value moldArg,
- llvm::SmallVectorImpl<mlir::Value> &lenParams) {
+static llvm::SmallVector<mlir::Value>
+getLengthParameters(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value moldArg) {
+ llvm::SmallVector<mlir::Value> lenParams;
// We pass derived types unboxed and so are not self-contained entities.
// Assume that unboxed derived types won't need length paramters.
if (!hlfir::isFortranEntity(moldArg))
- return;
+ return lenParams;
hlfir::genLengthParameters(loc, builder, hlfir::Entity{moldArg}, lenParams);
if (lenParams.empty())
- return;
+ return lenParams;
// The verifier for EmboxOp doesn't allow length parameters when the the
// character already has static LEN. genLengthParameters may still return them
@@ -277,6 +279,7 @@ static void getLengthParameters(fir::FirOpBuilder &builder, mlir::Location loc,
if (strTy && strTy.hasConstantLen())
lenParams.resize(0);
+ return lenParams;
}
static bool
@@ -329,9 +332,10 @@ class PopulateInitAndCleanupRegionsHelper {
argType{argType}, scalarInitValue{scalarInitValue},
allocatedPrivVarArg{allocatedPrivVarArg}, moldArg{moldArg},
initBlock{initBlock}, cleanupRegion{cleanupRegion}, kind{kind},
- sym{sym}, cannotHaveNonDefaultLowerBounds{cannotHaveLowerBounds},
- isDoConcurrent{isDoConcurrent},
- forceHeapAllocation{forceHeapAllocation} {
+ sym{sym},
+ lenParams(decltype(this->lenParams)::withFlags(
+ unsigned(cannotHaveLowerBounds) | (unsigned(isDoConcurrent) << 1) |
+ (unsigned(forceHeapAllocation) << 2))) {
valType = fir::unwrapRefType(argType);
}
@@ -371,17 +375,27 @@ class PopulateInitAndCleanupRegionsHelper {
const Fortran::semantics::Symbol *sym;
/// Any length parameters which have been fetched for the type
- mlir::SmallVector<mlir::Value> lenParams;
+ llvm::SmallVectorWithFlags<
+ mlir::Value,
+ llvm::CalculateSmallVectorDefaultInlinedElements<mlir::Value>::value, 3>
+ lenParams;
/// If the source variable being privatized definitely can't have non-default
/// lower bounds then we don't need to generate code to read them.
- bool cannotHaveNonDefaultLowerBounds;
+ bool getCannotHaveNonDefaultLowerBounds() const {
+ return lenParams.getFlag(0);
+ }
+ void setCannotHaveNonDefaultLowerBounds(bool Value) {
+ lenParams.setFlag(0, Value);
+ }
- bool isDoConcurrent;
- bool forceHeapAllocation;
+ bool getIsDoConcurrent() const { return lenParams.getFlag(1); }
+ void setIsDoConcurrent(bool Value) { lenParams.setFlag(1, Value); }
+ bool getForceHeapAllocation() const { return lenParams.getFlag(2); }
+ void setForceHeapAllocation(bool Value) { lenParams.setFlag(2, Value); }
void createYield(mlir::Value ret) {
- if (isDoConcurrent)
+ if (getIsDoConcurrent())
fir::YieldOp::create(builder, loc, ret);
else
mlir::omp::YieldOp::create(builder, loc, ret);
@@ -506,7 +520,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedScalar(
if (!shouldAllocateOnStack)
createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
- isDoConcurrent);
+ getIsDoConcurrent());
if (ifUnallocated)
builder.setInsertionPointAfter(ifUnallocated);
@@ -523,7 +537,7 @@ bool PopulateInitAndCleanupRegionsHelper::shouldAllocateTempOnStack(
// On the GPU, always allocate on the stack unless the user explicitly
// specifies otherwise since heap allocations are very expensive.
bool isGPU = offloadMod && offloadMod.getIsGPU();
- if (isGPU && forceHeapAllocation)
+ if (isGPU && getForceHeapAllocation())
return false;
if (isGPU && enableGPUHeapAlloc) {
// Check if it is adjustable array
@@ -540,7 +554,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
fir::BaseBoxType boxTy, bool needsInitialization) {
bool isAllocatableOrPointer =
mlir::isa<fir::HeapType, fir::PointerType>(boxTy.getEleTy());
- getLengthParameters(builder, loc, getLoadedMoldArg(), lenParams);
+ lenParams.assign(getLengthParameters(builder, loc, getLoadedMoldArg()));
fir::IfOp ifUnallocated{nullptr};
if (isAllocatableOrPointer) {
@@ -554,8 +568,8 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
// Special case for (possibly allocatable) arrays of polymorphic types
// e.g. !fir.class<!fir.heap<!fir.array<?x!fir.type<>>>>
if (source.isPolymorphic()) {
- fir::ShapeShiftOp shape =
- getShapeShift(builder, loc, source, cannotHaveNonDefaultLowerBounds);
+ fir::ShapeShiftOp shape = getShapeShift(
+ builder, loc, source, getCannotHaveNonDefaultLowerBounds());
mlir::Type arrayType = source.getElementOrSequenceType();
mlir::Value allocatedArray = fir::AllocMemOp::create(
builder, loc, arrayType, /*typeparams=*/mlir::ValueRange{},
@@ -571,7 +585,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
createYield(allocatedPrivVarArg);
mlir::OpBuilder::InsertionGuard guard(builder);
createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
- isDoConcurrent);
+ getIsDoConcurrent());
return;
}
@@ -588,7 +602,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
if (needsDealloc) {
mlir::OpBuilder::InsertionGuard guard(builder);
createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
- isDoConcurrent);
+ getIsDoConcurrent());
} else {
assert(!isAllocatableOrPointer &&
"Pointer-like arrays must be heap allocated");
@@ -599,8 +613,8 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxedArray(
// Put the temporary inside of a box:
// hlfir::genVariableBox doesn't handle non-default lower bounds
mlir::Value box;
- fir::ShapeShiftOp shapeShift = getShapeShift(builder, loc, getLoadedMoldArg(),
- cannotHaveNonDefaultLowerBounds);
+ fir::ShapeShiftOp shapeShift = getShapeShift(
+ builder, loc, getLoadedMoldArg(), getCannotHaveNonDefaultLowerBounds());
mlir::Type boxType = getLoadedMoldArg().getType();
if (mlir::isa<fir::BaseBoxType>(temp.getType()))
// the box created by the declare form createTempFromMold is missing
@@ -646,7 +660,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupBoxchar(
mlir::Value boxChar = charExprHelper.createEmboxChar(privateAddr, len);
createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
- isDoConcurrent);
+ getIsDoConcurrent());
builder.setInsertionPointToEnd(initBlock);
createYield(boxChar);
@@ -685,7 +699,7 @@ void PopulateInitAndCleanupRegionsHelper::initAndCleanupUnboxedDerivedType(
if (sym && hasFinalization(*sym))
createCleanupRegion(converter, loc, argType, cleanupRegion, sym,
- isDoConcurrent);
+ getIsDoConcurrent());
builder.setInsertionPointToEnd(initBlock);
createYield(allocatedPrivVarArg);
@@ -733,7 +747,7 @@ void PopulateInitAndCleanupRegionsHelper::populateByRefInitAndCleanupRegions() {
}
// TODO: don't do this unless it is needed
- getLengthParameters(builder, loc, getLoadedMoldArg(), lenParams);
+ lenParams.assign(getLengthParameters(builder, loc, getLoadedMoldArg()));
if (isPrivatization(kind) &&
mlir::isa<fir::PointerType>(boxTy.getEleTy())) {
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index 9e568af786910..7162940eb37d6 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -226,11 +226,11 @@ static fir::AliasAnalysis::Source mergeRegionBranchPredecessorSources(
// as true if any of the sources are true.
bool mergedApprox =
llvm::any_of(sources, [](const fir::AliasAnalysis::Source &s) {
- return s.approximateSource;
+ return s.getApproximateSource();
});
bool mergedCaptured =
llvm::any_of(sources, [](const fir::AliasAnalysis::Source &s) {
- return s.isCapturedInInternalProcedure;
+ return s.getIsCapturedInInternalProcedure();
});
fir::AliasAnalysis::SourceKind mergedKind;
@@ -317,10 +317,10 @@ static fir::AliasAnalysis::Source mergeRegionBranchPredecessorSources(
fir::AliasAnalysis::Source::AccessPath mergedPath;
if (allPathsSame) {
mergedPath = sources[0].accessPath;
- mergedPath.isApproximate |= mergedApprox;
+ mergedPath.setIsApproximate(mergedPath.isApproximate() || mergedApprox);
} else {
mergedPath = {};
- mergedPath.isApproximate = true;
+ mergedPath.setIsApproximate(true);
}
mlir::Type mergedTy = allTypesSame ? sources[0].valueType : fallbackType;
@@ -358,15 +358,16 @@ static fir::AliasAnalysis::Source mergeRegionBranchPredecessorSources(
unsigned idx = it->second;
auto &mergedScopedOrigin = mergedScopedOrigins[idx];
if (mergedScopedOrigin.isData != scopedOrigin.isData ||
- mergedScopedOrigin.accessPath.steps !=
- scopedOrigin.accessPath.steps) {
+ llvm::ArrayRef(mergedScopedOrigin.accessPath.steps) !=
+ llvm::ArrayRef(scopedOrigin.accessPath.steps)) {
// Mark as not-seen so the entry is dropped after this pred.
continue;
}
mergedScopedOrigin.attributes |= scopedOrigin.attributes;
mergedScopedOrigin.approximateSource |= scopedOrigin.approximateSource;
- mergedScopedOrigin.accessPath.isApproximate |=
- scopedOrigin.accessPath.isApproximate;
+ mergedScopedOrigin.accessPath.setIsApproximate(
+ mergedScopedOrigin.accessPath.isApproximate() ||
+ scopedOrigin.accessPath.isApproximate());
seenThisPred[idx] = true;
}
// Drop entries this predecessor did not match. Iterate in reverse
@@ -413,7 +414,7 @@ void AliasAnalysis::Source::AccessPath::print(llvm::raw_ostream &os) const {
}
}
os << "]";
- if (isApproximate)
+ if (isApproximate())
os << "(~)";
}
@@ -776,7 +777,8 @@ AliasResult AliasAnalysis::alias(Source lhsSrc, Source rhsSrc, mlir::Value lhs,
}
}
- bool approximateSource = lhsSrc.approximateSource || rhsSrc.approximateSource;
+ bool approximateSource =
+ lhsSrc.getApproximateSource() || rhsSrc.getApproximateSource();
LLVM_DEBUG(llvm::dbgs() << "\nAliasAnalysis::alias\n";
llvm::dbgs() << " lhs: " << lhs << "\n";
llvm::dbgs() << " lhsSrc: " << lhsSrc << "\n";
@@ -1120,7 +1122,7 @@ ModRefResult AliasAnalysis::getCallModRef(Operation *op, Value var) {
// procedures may be captured or passed. As this is tricky to analyze, always
// consider such variables may be accessed in any calls.
if (varSrc.kind == fir::AliasAnalysis::SourceKind::HostAssoc ||
- varSrc.isCapturedInInternalProcedure)
+ varSrc.getIsCapturedInInternalProcedure())
return ModRefResult::getModAndRef();
// At that stage, it has been ruled out that local (including the saved ones)
// and dummy cannot be indirectly accessed in the call.
@@ -1240,8 +1242,8 @@ void AliasAnalysisRecursiveEffectsCache::buildSummary(mlir::Operation *op,
// conservatively assume both Mod and Ref (this mirrors the uncached
// AliasAnalysis::getModRef which returns ModAndRef in this case).
if (!isRecursive) {
- out.hasUnknownWrite = true;
- out.hasUnknownRead = true;
+ out.setHasUnknownWrite(true);
+ out.setHasUnknownRead(true);
}
return;
}
@@ -1264,9 +1266,9 @@ void AliasAnalysisRecursiveEffectsCache::buildSummary(mlir::Operation *op,
if (!v) {
if (isRead)
- out.hasUnknownRead = true;
+ out.setHasUnknownRead(true);
if (isWrite)
- out.hasUnknownWrite = true;
+ out.setHasUnknownWrite(true);
continue;
}
@@ -1297,8 +1299,8 @@ AliasAnalysisRecursiveEffectsCache::getModRefFromSummary(mlir::Operation *op,
}
const Summary &s = it->second;
- bool mod = s.hasUnknownWrite;
- bool ref = s.hasUnknownRead;
+ bool mod = s.getHasUnknownWrite();
+ bool ref = s.getHasUnknownRead();
if (!mod) {
for (mlir::Value v : s.writeLocations) {
@@ -1566,7 +1568,7 @@ AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint,
// Access path steps collected during the backward walk (leaf-to-root order).
// Reversed into the final AccessPath at the end, unless the box-load branch
// composes the full path directly.
- llvm::SmallVector<Source::PathStep, 4> pathSteps;
+ llvm::SmallVectorWithFlags<Source::PathStep, 4> pathSteps;
Source::AccessPath accessPath;
bool accessPathFinalized{false};
@@ -1686,9 +1688,9 @@ AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint,
/*getLastInstantiationPoint=*/false,
collectScopedOrigins);
attributes |= boxSrc.attributes;
- approximateSource |= boxSrc.approximateSource;
+ approximateSource |= boxSrc.getApproximateSource();
isCapturedInInternalProcedure |=
- boxSrc.isCapturedInInternalProcedure;
+ boxSrc.getIsCapturedInInternalProcedure();
if (getLastInstantiationPoint) {
if (!instantiationPoint)
@@ -1707,8 +1709,8 @@ AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint,
accessPath.steps.push_back(derefStep);
for (int i = pathSteps.size() - 1; i >= 0; --i)
accessPath.steps.push_back(pathSteps[i]);
- accessPath.isApproximate =
- boxSrc.accessPath.isApproximate || approximateSource;
+ accessPath.setIsApproximate(boxSrc.accessPath.isApproximate() ||
+ approximateSource);
accessPathFinalized = true;
// Rebase each forwarded ScopedOrigin from the inner walk's
@@ -1720,7 +1722,9 @@ AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint,
scopedOrigin.accessPath.steps.push_back(derefStep);
for (int i = pathSteps.size() - 1; i >= 0; --i)
scopedOrigin.accessPath.steps.push_back(pathSteps[i]);
- scopedOrigin.accessPath.isApproximate |= approximateSource;
+ scopedOrigin.accessPath.setIsApproximate(
+ scopedOrigin.accessPath.isApproximate() ||
+ approximateSource);
if (isPointerBox)
scopedOrigin.attributes.set(Attribute::Pointer);
scopedOrigin.approximateSource |= approximateSource;
@@ -1873,7 +1877,7 @@ AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint,
scopedOrigin.declValue = opResult;
scopedOrigin.accessPath.steps.assign(pathSteps.rbegin(),
pathSteps.rend());
- scopedOrigin.accessPath.isApproximate = approximateSource;
+ scopedOrigin.accessPath.setIsApproximate(approximateSource);
scopedOrigin.attributes = attributes;
scopedOrigin.approximateSource = approximateSource;
scopedOrigin.isData = followingData;
@@ -2068,10 +2072,13 @@ AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint,
collectScopedOrigins));
regionBranchReturn = mergeRegionBranchPredecessorSources(
predSources, v, ty, followingData);
- regionBranchReturn->attributes |= attributes;
- regionBranchReturn->approximateSource |= approximateSource;
- regionBranchReturn->isCapturedInInternalProcedure |=
- isCapturedInInternalProcedure;
+ auto &returnSource = *regionBranchReturn;
+ returnSource.attributes |= attributes;
+ returnSource.setApproximateSource(
+ int(returnSource.getApproximateSource()) | (approximateSource));
+ returnSource.setIsCapturedInInternalProcedure(
+ int(returnSource.getIsCapturedInInternalProcedure()) |
+ (isCapturedInInternalProcedure));
// Prepend the outer (leaf-closer) scopedOrigins -- declares
// already crossed between leaf and this region-branch op --
// to the merged predecessors' snapshots. The inner snapshots'
@@ -2085,7 +2092,7 @@ AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint,
combined.append(scopedOrigins.begin(), scopedOrigins.end());
combined.append(regionBranchReturn->scopedOrigins.begin(),
regionBranchReturn->scopedOrigins.end());
- regionBranchReturn->scopedOrigins = std::move(combined);
+ regionBranchReturn->scopedOrigins.assign(std::move(combined));
}
breakFromLoop = true;
})
@@ -2129,7 +2136,7 @@ AliasAnalysis::getSourceImpl(mlir::Value v, bool getLastInstantiationPoint,
if (!accessPathFinalized) {
std::reverse(pathSteps.begin(), pathSteps.end());
accessPath.steps = std::move(pathSteps);
- accessPath.isApproximate = approximateSource;
+ accessPath.setIsApproximate(approximateSource);
}
if (type == SourceKind::Global) {
@@ -2234,7 +2241,7 @@ fir::AliasAnalysis::Source fir::AliasAnalysis::buildSourceAtDeclare(
// "declare-as-root, original-query-as-leaf".
source.accessPath = scopedOrigin.accessPath;
source.attributes = scopedOrigin.attributes;
- source.approximateSource = scopedOrigin.approximateSource;
+ source.setApproximateSource(scopedOrigin.approximateSource);
source.origin.isData = scopedOrigin.isData;
return source;
}
diff --git a/flang/lib/Optimizer/Builder/TemporaryStorage.cpp b/flang/lib/Optimizer/Builder/TemporaryStorage.cpp
index 0233fc9f023de..42998e348cb52 100644
--- a/flang/lib/Optimizer/Builder/TemporaryStorage.cpp
+++ b/flang/lib/Optimizer/Builder/TemporaryStorage.cpp
@@ -145,8 +145,7 @@ fir::factory::ArrayTemp::ArrayTemp(mlir::Location loc,
llvm::ArrayRef<mlir::Value> lowerBounds,
llvm::ArrayRef<mlir::Value> lengths,
bool allocateOnHeap, llvm::StringRef name)
- : allocateOnHeap{allocateOnHeap},
- typeParams{lengths.begin(), lengths.end()} {
+ : typeParams(unsigned(allocateOnHeap), lengths.begin(), lengths.end()) {
assert(extents.size() == lowerBounds.size() &&
"extents and lowerBounds must have the same size");
assert(extents.size() == declaredType.getDimension() &&
@@ -194,22 +193,22 @@ void fir::factory::ArrayTemp::pushValue(mlir::Location loc,
// Match HomogeneousScalarStack: derived types go through the runtime path.
if (!entity.hasIntrinsicType())
TODO(loc, "creating ArrayTemp for derived types");
- mlir::Value addr =
- genArrayTempElementAddr(loc, builder, temp, indices, typeParams);
+ mlir::Value addr = genArrayTempElementAddr(
+ loc, builder, temp, indices, llvm::ArrayRef<mlir::Value>(typeParams));
hlfir::AssignOp::create(builder, loc, value, addr);
}
mlir::Value fir::factory::ArrayTemp::fetch(mlir::Location loc,
fir::FirOpBuilder &builder,
mlir::ValueRange indices) {
- mlir::Value addr =
- genArrayTempElementAddr(loc, builder, temp, indices, typeParams);
+ mlir::Value addr = genArrayTempElementAddr(
+ loc, builder, temp, indices, llvm::ArrayRef<mlir::Value>(typeParams));
return hlfir::loadTrivialScalar(loc, builder, hlfir::Entity{addr});
}
void fir::factory::ArrayTemp::destroy(mlir::Location loc,
fir::FirOpBuilder &builder) {
- if (allocateOnHeap) {
+ if (getAllocateOnHeap()) {
auto declare = temp.getDefiningOp<hlfir::DeclareOp>();
assert(declare && "temp must have been declared");
fir::FreeMemOp::create(builder, loc, declare.getMemref());
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp
index dcc40c7b25c5c..d82dc9ac4c531 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp
@@ -30,6 +30,7 @@
#include "mlir/IR/IRMapping.h"
#include "mlir/Transforms/DialectConversion.h"
#include "mlir/Transforms/RegionUtils.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/Debug.h"
#include <unordered_set>
@@ -297,7 +298,7 @@ class OrderedAssignmentRewriter {
/// Construct stack in the current run. This allows setting back the insertion
/// point correctly when leaving a node that requires a fir.do_loop or fir.if
/// operation.
- llvm::SmallVector<mlir::Operation *> constructStack;
+ llvm::SmallVectorWithFlags<mlir::Operation *> constructStack;
/// Current where loop nest, if any.
std::optional<hlfir::LoopNest> whereLoopNest;
@@ -322,7 +323,8 @@ class OrderedAssignmentRewriter {
/// When allocating temporary storage inlined, indicate if the storage should
/// be heap or stack allocated. Temporary allocated with the runtime are heap
/// allocated by the runtime.
- bool allocateOnHeap = true;
+ bool getAllocateOnHeap() const { return !constructStack.getFlag(0); }
+ void setAllocateOnHeap(bool Value) { constructStack.setFlag(0, !Value); }
};
} // namespace
@@ -1239,10 +1241,10 @@ void OrderedAssignmentRewriter::generateSaveEntity(
auto sequenceType = mlir::cast<fir::SequenceType>(
builder.getVarLenSeqTy(entityType, /*rank=*/loopNest.size()));
temp = insertSavedEntity(
- region,
- fir::factory::ArrayTemp{loc, builder, sequenceType, tempExtents,
- tempLowerBounds,
- /*lengths=*/{}, allocateOnHeap, tempName});
+ region, fir::factory::ArrayTemp{loc, builder, sequenceType,
+ tempExtents, tempLowerBounds,
+ /*lengths=*/{}, getAllocateOnHeap(),
+ tempName});
} else if (loopShapeCanBePreComputed && fir::isa_trivial(entityType)) {
mlir::Value loopExtent =
computeLoopNestIterationNumber(loc, builder, loopNest);
@@ -1251,7 +1253,7 @@ void OrderedAssignmentRewriter::generateSaveEntity(
temp = insertSavedEntity(region,
fir::factory::HomogeneousScalarStack{
loc, builder, sequenceType, loopExtent,
- /*lenParams=*/{}, allocateOnHeap,
+ /*lenParams=*/{}, getAllocateOnHeap(),
/*stackThroughLoops=*/true, tempName});
} else {
// If the number of iteration is not known, or if the values at each
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp
index c99304df57c35..bb1e57c2ead49 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp
@@ -13,6 +13,7 @@
#include "flang/Optimizer/Dialect/FortranVariableInterface.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "mlir/IR/OperationSupport.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "flang-ordered-assignment"
@@ -180,7 +181,9 @@ class Scheduler {
public:
Scheduler(hlfir::OrderedAssignmentTreeOpInterface root,
bool tryFusingAssignments)
- : root{root}, tryFusingAssignments{tryFusingAssignments} {}
+ : root{root}, independentEvaluationEffects(
+ decltype(this->independentEvaluationEffects)::withFlags(
+ (unsigned(tryFusingAssignments) << 2))) {}
/// Start scheduling an assignment. Gather the write side effect from the
/// assignment.
@@ -266,10 +269,19 @@ class Scheduler {
llvm::SmallVector<hlfir::DetailedEffectInstance> parentEvaluationEffects;
/// Same as parentEvaluationEffects, but for the current "leaf group" being
/// analyzed scheduled.
- llvm::SmallVector<hlfir::DetailedEffectInstance> independentEvaluationEffects;
+ llvm::SmallVectorWithFlags<hlfir::DetailedEffectInstance,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ hlfir::DetailedEffectInstance>::value,
+ 3>
+ independentEvaluationEffects;
/// Were any region saved for the current assignment?
- bool savedAnyRegionForCurrentAssignment = false;
+ bool getSavedAnyRegionForCurrentAssignment() const {
+ return independentEvaluationEffects.getFlag(0);
+ }
+ void setSavedAnyRegionForCurrentAssignment(bool Value) {
+ independentEvaluationEffects.setFlag(0, Value);
+ }
// Schedule being built.
hlfir::Schedule schedule;
@@ -280,11 +292,24 @@ class Scheduler {
/// Is schedule.back() a schedule that is only saving region with read
/// effects?
- bool currentRunIsReadOnly = false;
+ bool getCurrentRunIsReadOnly() const {
+ return independentEvaluationEffects.getFlag(1);
+ }
+ void setCurrentRunIsReadOnly(bool Value) {
+ independentEvaluationEffects.setFlag(1, Value);
+ }
/// Option to tell if the scheduler should try fusing to assignments in the
/// same loops.
- const bool tryFusingAssignments;
+ bool getTryFusingAssignments() const {
+ return independentEvaluationEffects.getFlag(2);
+ }
+
+public:
+ Scheduler(const Scheduler &) = default;
+ Scheduler(Scheduler &&) = default;
+ Scheduler &operator=(const Scheduler &) = delete;
+ Scheduler &operator=(Scheduler &&) = delete;
};
} // namespace
@@ -783,7 +808,7 @@ void Scheduler::saveEvaluationIfConflict(mlir::Region &yieldRegion,
void Scheduler::saveEvaluation(
mlir::Region &yieldRegion,
llvm::ArrayRef<hlfir::DetailedEffectInstance> effects, bool anyWrite) {
- savedAnyRegionForCurrentAssignment = true;
+ setSavedAnyRegionForCurrentAssignment(true);
auto &state = regionStates[&yieldRegion];
if (state.modifiedInRun) {
// The region was modified in a previous run, but we now realize we need its
@@ -807,13 +832,13 @@ void Scheduler::saveEvaluation(
// could try to prove the effects do not conflict with the previous
// schedule.
schedule.emplace_back(hlfir::Run{});
- currentRunIsReadOnly = false;
- } else if (!currentRunIsReadOnly) {
+ setCurrentRunIsReadOnly(false);
+ } else if (!getCurrentRunIsReadOnly()) {
// For now, do not try to fuse an evaluation with a previous
// run that contains any write effects. One could try to prove
// that "effects" do not conflict with the current run assignments.
schedule.emplace_back(hlfir::Run{});
- currentRunIsReadOnly = true;
+ setCurrentRunIsReadOnly(true);
}
// Otherwise, save the yielded entity in the current run, that already
// saving other read only entities.
@@ -833,7 +858,7 @@ void Scheduler::saveEvaluation(
bool Scheduler::canFuseAssignmentWithPreviousRun() {
// If a region was saved for the current assignment, the previous
// run is already known to conflict. Skip the analysis.
- if (savedAnyRegionForCurrentAssignment || schedule.empty())
+ if (getSavedAnyRegionForCurrentAssignment() || schedule.empty())
return false;
auto &previousRunEffects = schedule.back().memoryEffects;
return !conflict(previousRunEffects, assignEffects).isAny() &&
@@ -873,8 +898,8 @@ void Scheduler::finishSchedulingAssignment(hlfir::RegionAssignOp assign,
bool leafRegionsMayOnlyRead) {
// Schedule the assignment in a new run, unless it can be fused with the
// previous run (if enabled and proven safe).
- currentRunIsReadOnly = false;
- bool fuse = tryFusingAssignments && canFuseAssignmentWithPreviousRun();
+ setCurrentRunIsReadOnly(false);
+ bool fuse = getTryFusingAssignments() && canFuseAssignmentWithPreviousRun();
if (!fuse) {
// If we cannot fuse, we are about to start a new run.
// Check if any parent region was modified in a previous run and needs to be
@@ -921,7 +946,7 @@ void Scheduler::finishSchedulingAssignment(hlfir::RegionAssignOp assign,
assignEvaluateEffects.clear();
parentEvaluationEffects.clear();
independentEvaluationEffects.clear();
- savedAnyRegionForCurrentAssignment = false;
+ setSavedAnyRegionForCurrentAssignment(false);
LLVM_DEBUG(logAssignmentEvaluation(llvm::dbgs(), schedule.size(), assign));
}
diff --git a/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp b/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
index 5be6ec35a3972..b5f40aba38dfc 100644
--- a/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
+++ b/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
@@ -71,6 +71,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/Casting.h"
@@ -196,8 +197,9 @@ class FIRToMemRef : public fir::impl::FIRToMemRefBase<FIRToMemRef> {
struct SliceInfo {
SmallVector<Value> shapeVec;
SmallVector<Value> shiftVec;
- SmallVector<Value> sliceVec;
- bool hasProjectedSlice = false;
+ llvm::SmallVectorWithFlags<Value> sliceVec;
+ bool getHasProjectedSlice() const { return sliceVec.getFlag(0); }
+ void setHasProjectedSlice(bool Value) { sliceVec.setFlag(0, Value); }
// Constant value of the first projected-slice field, if any.
std::optional<std::int64_t> projectedSliceStart;
};
@@ -477,7 +479,7 @@ void FIRToMemRef::collectSliceInfoFrom(OpTy op, SliceInfo &info) const {
if (auto sliceOp = getSliceOp(op.getSlice())) {
if (hasProjectedSlice(sliceOp)) {
- info.hasProjectedSlice = true;
+ info.setHasProjectedSlice(true);
info.projectedSliceStart = getProjectedSliceStartIfConstant(sliceOp);
}
auto triples = sliceOp.getTriples();
@@ -826,7 +828,7 @@ FIRToMemRef::getMemrefIndices(fir::ArrayCoorOp arrayCoorOp, Operation *memref,
}
SmallVector<Value> &shiftVec = sliceInfo.shiftVec;
- SmallVector<Value> &sliceVec = sliceInfo.sliceVec;
+ auto &sliceVec = sliceInfo.sliceVec;
SmallVector<Value> sliceLbs, sliceStrides;
for (size_t i = 0; i < sliceVec.size(); i += 3) {
sliceLbs.push_back(castTypeToIndexType(sliceVec[i], rewriter));
@@ -992,7 +994,7 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
else if (auto rebox = firMemref.getDefiningOp<fir::ReboxOp>())
collectSliceInfoFrom(rebox, sliceInfo);
- if (!sliceInfo.hasProjectedSlice && sliceInfo.shapeVec.empty()) {
+ if (!sliceInfo.getHasProjectedSlice() && sliceInfo.shapeVec.empty()) {
auto shapeVal = arrayCoorOp.getShape();
if (shapeVal &&
mlir::isa<fir::ShapeType, fir::ShapeShiftType>(shapeVal.getType())) {
@@ -1025,7 +1027,7 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
// each load/store touches exactly sizeof(T) bytes.
auto srcTy = cast<MemRefType>((*converted).getType());
std::optional<int64_t> complexPartIdx;
- if (sliceInfo.hasProjectedSlice) {
+ if (sliceInfo.getHasProjectedSlice()) {
if (auto complexTy = dyn_cast<mlir::ComplexType>(srcTy.getElementType())) {
if (!sliceInfo.projectedSliceStart ||
(*sliceInfo.projectedSliceStart != 0 &&
@@ -1088,8 +1090,8 @@ FIRToMemRef::convertArrayCoorOp(Operation *memOp, fir::ArrayCoorOp arrayCoorOp,
shapeVec.empty() || (firMemrefIsBox && !firMemrefIsEmbox);
if (descriptorOwnsLayout) {
// Plain `!fir.ref` without recoverable shape extents cannot use fir.box_*.
- if (shapeVec.empty() && !sliceInfo.hasProjectedSlice && !isDescriptor &&
- !isRebox)
+ if (shapeVec.empty() && !sliceInfo.getHasProjectedSlice() &&
+ !isDescriptor && !isRebox)
return failure();
// Complex %re/%im: memref_stride = box_dims_byte_stride / sizeof(T),
diff --git a/flang/unittests/Optimizer/AliasAnalysisCacheTest.cpp b/flang/unittests/Optimizer/AliasAnalysisCacheTest.cpp
index 4d1abfff7e258..8e34d1947aa71 100644
--- a/flang/unittests/Optimizer/AliasAnalysisCacheTest.cpp
+++ b/flang/unittests/Optimizer/AliasAnalysisCacheTest.cpp
@@ -18,6 +18,25 @@
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Support/InitFIR.h"
+TEST(AliasAnalysisAccessPathTest, ApproximationParticipatesInPathEquality) {
+ using Path = fir::AliasAnalysis::Source::AccessPath;
+ using Step = fir::AliasAnalysis::Source::PathStep;
+ Path exact;
+ exact.steps.assign(8, Step{Step::Kind::PointerDeref, {}});
+ Path approximate = exact;
+ approximate.setIsApproximate(true);
+ EXPECT_NE(exact, approximate);
+ // Comparing just the steps must continue to ignore approximation.
+ EXPECT_EQ(llvm::ArrayRef(exact.steps), llvm::ArrayRef(approximate.steps));
+
+ Path moved = std::move(approximate);
+ EXPECT_TRUE(moved.isApproximate());
+ moved.steps.clear();
+ EXPECT_TRUE(moved.isApproximate());
+ moved.setIsApproximate(false);
+ EXPECT_FALSE(moved.isApproximate());
+}
+
struct AliasAnalysisCacheTest : public testing::Test {
public:
void SetUp() override {
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 2f2b6094fbc2c..dd391817f0fff 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -56,7 +56,7 @@ SectionChunk::SectionChunk(ObjFile *f, const coff_section *h, Kind k)
// files will be built with -ffunction-sections or /Gy, so most things worth
// stripping will be in a comdat.
if (file)
- live = !file->symtab.ctx.config.doGC || !isCOMDAT();
+ live = !file->symtab.ctx.config.getDoGC() || !isCOMDAT();
else
live = true;
}
@@ -844,7 +844,7 @@ void StringChunk::writeTo(uint8_t *buf) const {
}
ImportThunkChunk::ImportThunkChunk(COFFLinkerContext &ctx, Defined *s)
- : NonSectionCodeChunk(ImportThunkKind), live(!ctx.config.doGC),
+ : NonSectionCodeChunk(ImportThunkKind), live(!ctx.config.getDoGC()),
impSymbol(s), ctx(ctx) {}
ImportThunkChunkX64::ImportThunkChunkX64(COFFLinkerContext &ctx, Defined *s)
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 7546da219c440..5e55aa28c5f94 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
@@ -121,13 +122,19 @@ struct Configuration {
llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
bool machineInferred = false;
size_t wordsize;
- bool verbose = false;
+ bool getVerbose() const { return dtltoCompilerArgs.getFlag(0); }
+ bool setVerbose(bool Value) {
+ dtltoCompilerArgs.setFlag(0, Value);
+ return Value;
+ }
WindowsSubsystem subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
bool noEntry = false;
std::string outputFile;
std::string importName;
- bool demangle = true;
- bool doGC = true;
+ bool getDemangle() const { return !dtltoCompilerArgs.getFlag(1); }
+ void setDemangle(bool Value) { dtltoCompilerArgs.setFlag(1, !Value); }
+ bool getDoGC() const { return !dtltoCompilerArgs.getFlag(2); }
+ void setDoGC(bool Value) { dtltoCompilerArgs.setFlag(2, !Value); }
ICFLevel doICF = ICFLevel::None;
bool tailMerge;
bool relocatable = true;
@@ -145,7 +152,7 @@ struct Configuration {
bool showSummary = false;
bool printSearchPaths = false;
unsigned debugTypes = static_cast<unsigned>(DebugType::None);
- llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> mllvmOpts;
std::vector<std::string> natvisFiles;
llvm::StringMap<std::string> namedStreams;
llvm::SmallString<128> pdbAltPath;
@@ -158,12 +165,18 @@ struct Configuration {
std::vector<Symbol *> gcroot;
llvm::StringSet<> noDefaultLibs;
- bool noDefaultLibAll = false;
+ bool getNoDefaultLibAll() const { return dtltoCompilerArgs.getFlag(3); }
+ bool setNoDefaultLibAll(bool Value) {
+ dtltoCompilerArgs.setFlag(3, Value);
+ return Value;
+ }
// True if we are creating a DLL.
- bool dll = false;
+ bool getDll() const { return dtltoCompilerPrependArgs.getFlag(0); }
+ void setDll(bool Value) { dtltoCompilerPrependArgs.setFlag(0, Value); }
StringRef implib;
- bool noimplib = false;
+ bool getNoimplib() const { return dtltoCompilerPrependArgs.getFlag(1); }
+ void setNoimplib(bool Value) { dtltoCompilerPrependArgs.setFlag(1, Value); }
llvm::StringSet<> delayLoads;
std::map<std::string, int> dllOrder;
Symbol *arm64ECIcallHelper = nullptr;
@@ -198,22 +211,30 @@ struct Configuration {
StringRef dtltoDistributor;
// Used for /thinlto-distributor-arg:<arg>
- llvm::SmallVector<llvm::StringRef, 0> dtltoDistributorArgs;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> dtltoDistributorArgs;
// Used for /thinlto-remote-compiler:<path>
StringRef dtltoCompiler;
// Used for /thinlto-remote-compiler-prepend-arg:<arg>
- llvm::SmallVector<llvm::StringRef, 0> dtltoCompilerPrependArgs;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> dtltoCompilerPrependArgs;
// Used for /thinlto-remote-compiler-arg:<arg>
- llvm::SmallVector<llvm::StringRef, 0> dtltoCompilerArgs;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> dtltoCompilerArgs;
// Used for /fat-lto-objects
- bool fatLTOObjects = false;
+ bool getFatLTOObjects() const { return dtltoCompilerPrependArgs.getFlag(2); }
+ void setFatLTOObjects(bool Value) {
+ dtltoCompilerPrependArgs.setFlag(2, Value);
+ }
// Used for /opt:[no]ltodebugpassmanager
- bool ltoDebugPassManager = false;
+ bool getLtoDebugPassManager() const {
+ return dtltoCompilerPrependArgs.getFlag(3);
+ }
+ void setLtoDebugPassManager(bool Value) {
+ dtltoCompilerPrependArgs.setFlag(3, Value);
+ }
// Used for /merge:from=to (e.g. /merge:.rdata=.text)
std::map<StringRef, StringRef> merge;
@@ -230,7 +251,8 @@ struct Configuration {
ManifestKind manifest = Default;
int manifestID = 1;
llvm::SetVector<StringRef> manifestDependencies;
- bool manifestUAC = true;
+ bool getManifestUAC() const { return !dtltoDistributorArgs.getFlag(0); }
+ void setManifestUAC(bool Value) { dtltoDistributorArgs.setFlag(0, !Value); }
std::vector<std::string> manifestInput;
StringRef manifestLevel = "'asInvoker'";
StringRef manifestUIAccess = "'false'";
@@ -255,7 +277,11 @@ struct Configuration {
std::string mapFile;
// Used for /mapinfo.
- bool mapInfo = false;
+ bool getMapInfo() const { return dtltoDistributorArgs.getFlag(1); }
+ bool setMapInfo(bool Value) {
+ dtltoDistributorArgs.setFlag(1, Value);
+ return Value;
+ }
// Used for /thinlto-index-only:
llvm::StringRef thinLTOIndexOnlyArg;
@@ -278,13 +304,23 @@ struct Configuration {
llvm::StringRef ltoObjPath;
// Used for /lto-cs-profile-generate:
- bool ltoCSProfileGenerate = false;
+ bool getLtoCSProfileGenerate() const {
+ return dtltoDistributorArgs.getFlag(2);
+ }
+ void setLtoCSProfileGenerate(bool Value) {
+ dtltoDistributorArgs.setFlag(2, Value);
+ }
// Used for /lto-cs-profile-path
llvm::StringRef ltoCSProfileFile;
// Used for /lto-pgo-warn-mismatch:
- bool ltoPGOWarnMismatch = true;
+ bool getLtoPGOWarnMismatch() const {
+ return !dtltoDistributorArgs.getFlag(3);
+ }
+ void setLtoPGOWarnMismatch(bool Value) {
+ dtltoDistributorArgs.setFlag(3, !Value);
+ }
// Used for /lto-sample-profile:
llvm::StringRef ltoSampleProfileName;
@@ -293,7 +329,8 @@ struct Configuration {
llvm::MapVector<std::pair<const SectionChunk *, const SectionChunk *>,
uint64_t>
callGraphProfile;
- bool callGraphProfileSort = false;
+ bool getCallGraphProfileSort() const { return mllvmOpts.getFlag(0); }
+ void setCallGraphProfileSort(bool Value) { mllvmOpts.setFlag(0, Value); }
// Used for /print-symbol-order:
StringRef printSymbolOrder;
@@ -354,14 +391,20 @@ struct Configuration {
bool pseudoRelocs = false;
bool stdcallFixup = false;
bool writeCheckSum = false;
- bool prefetchInputs = false;
+ bool getPrefetchInputs() const { return mllvmOpts.getFlag(1); }
+ bool setPrefetchInputs(bool Value) {
+ mllvmOpts.setFlag(1, Value);
+ return Value;
+ }
EmitKind emit = EmitKind::Obj;
- bool allowDuplicateWeak = false;
+ bool getAllowDuplicateWeak() const { return mllvmOpts.getFlag(2); }
+ void setAllowDuplicateWeak(bool Value) { mllvmOpts.setFlag(2, Value); }
BuildIDHash buildIDHash = BuildIDHash::None;
llvm::StringRef optRemarksFilename;
llvm::StringRef optRemarksPasses;
llvm::StringRef optRemarksFormat;
- bool optRemarksWithHotness = false;
+ bool getOptRemarksWithHotness() const { return mllvmOpts.getFlag(3); }
+ void setOptRemarksWithHotness(bool Value) { mllvmOpts.setFlag(3, Value); }
std::optional<uint64_t> optRemarksHotnessThreshold = 0;
};
diff --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp
index 0999c918eb04f..17f321ec788c8 100644
--- a/lld/COFF/DebugTypes.cpp
+++ b/lld/COFF/DebugTypes.cpp
@@ -236,7 +236,7 @@ void TpiSource::remapRecord(MutableArrayRef<uint8_t> rec,
reinterpret_cast<TypeIndex *>(contents.data() + ref.Offset), ref.Count);
for (TypeIndex &ti : indices) {
if (!remapTypeIndex(ti, ref.Kind)) {
- if (ctx.config.verbose) {
+ if (ctx.config.getVerbose()) {
uint16_t kind =
reinterpret_cast<const RecordPrefix *>(rec.data())->RecordKind;
StringRef fname = file ? file->getName() : "<unknown PDB>";
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index ecbb5e9fff4e1..b00b2e6b4a43d 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -282,7 +282,7 @@ InputFile *LinkerDriver::addObjectFile(COFFLinkerContext &ctx,
}
}
- if (ctx.config.fatLTOObjects) {
+ if (ctx.config.getFatLTOObjects()) {
Expected<MemoryBufferRef> fatLTOData =
IRObjectFile::findBitcodeInObject(*coffObj);
@@ -408,7 +408,7 @@ void LinkerDriver::handleReproFile(StringRef path, InputOpt inputOpt) {
void LinkerDriver::enqueuePath(StringRef path, bool lazy, InputOpt inputOpt) {
auto future = std::make_shared<std::future<MBErrPair>>(
- createFutureForFile(std::string(path), ctx.config.prefetchInputs));
+ createFutureForFile(std::string(path), ctx.config.getPrefetchInputs()));
std::string pathStr = std::string(path);
enqueueTask([=]() {
llvm::TimeTraceScope timeScope("File: ", path);
@@ -429,7 +429,7 @@ void LinkerDriver::enqueuePath(StringRef path, bool lazy, InputOpt inputOpt) {
mb = std::move(*retryMb);
// Prefetch memory pages in the background as we will need them soon
// enough.
- if (ctx.config.prefetchInputs)
+ if (ctx.config.getPrefetchInputs())
mb->willNeedIfMmap();
}
} else {
@@ -528,7 +528,7 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
"could not get the filename for the member defining symbol " +
toCOFFString(ctx, sym));
auto future = std::make_shared<std::future<MBErrPair>>(
- createFutureForFile(childName, ctx.config.prefetchInputs));
+ createFutureForFile(childName, ctx.config.getPrefetchInputs()));
enqueueTask([=]() {
auto mbOrErr = future->get();
if (mbOrErr.second)
@@ -751,7 +751,7 @@ StringRef LinkerDriver::findLib(StringRef filename) {
// consideration. This never returns the same path (in that case,
// it returns std::nullopt).
std::optional<StringRef> LinkerDriver::findLibIfNew(StringRef filename) {
- if (ctx.config.noDefaultLibAll)
+ if (ctx.config.getNoDefaultLibAll())
return std::nullopt;
if (!visitedLibs.insert(filename.lower()).second)
return std::nullopt;
@@ -927,8 +927,8 @@ void LinkerDriver::addLibSearchPaths() {
uint64_t LinkerDriver::getDefaultImageBase() {
if (ctx.config.is64())
- return ctx.config.dll ? 0x180000000 : 0x140000000;
- return ctx.config.dll ? 0x10000000 : 0x400000;
+ return ctx.config.getDll() ? 0x180000000 : 0x140000000;
+ return ctx.config.getDll() ? 0x10000000 : 0x400000;
}
static std::string rewritePath(StringRef s) {
@@ -1069,8 +1069,8 @@ std::string LinkerDriver::getImportName(bool asLib) {
} else {
out.assign(ctx.config.importName);
if (!sys::path::has_extension(out))
- sys::path::replace_extension(out,
- (ctx.config.dll || asLib) ? ".dll" : ".exe");
+ sys::path::replace_extension(
+ out, (ctx.config.getDll() || asLib) ? ".dll" : ".exe");
}
return std::string(out);
@@ -1491,7 +1491,7 @@ void LinkerDriver::pullArm64ECIcallHelper() {
// than MinGW in the case that nothing is explicitly exported.
void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
if (!args.hasArg(OPT_export_all_symbols)) {
- if (!ctx.config.dll)
+ if (!ctx.config.getDll())
return;
if (ctx.symtab.hadExplicitExports ||
@@ -1777,8 +1777,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Handle /verbose
if (args.hasArg(OPT_verbose))
- config->verbose = true;
- ctx.e.verbose = config->verbose;
+ config->setVerbose(true);
+ ctx.e.verbose = config->getVerbose();
// Handle /force or /force:unresolved
if (args.hasArg(OPT_force, OPT_force_unresolved))
@@ -1851,7 +1851,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
}
// Handle /demangle
- config->demangle = args.hasFlag(OPT_demangle, OPT_demangle_no, true);
+ config->setDemangle(args.hasFlag(OPT_demangle, OPT_demangle_no, true));
// Handle /debugtype
config->debugTypes = parseDebugTypes(ctx, args);
@@ -1903,7 +1903,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Handle /dll
if (args.hasArg(OPT_dll)) {
- config->dll = true;
+ config->setDll(true);
config->manifestID = 2;
}
@@ -1953,7 +1953,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Handle /nodefaultlib
if (args.hasArg(OPT_nodefaultlib_all))
- config->noDefaultLibAll = true;
+ config->setNoDefaultLibAll(true);
// Handle /base
if (auto *arg = args.getLastArg(OPT_base))
@@ -2035,7 +2035,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (auto *arg = args.getLastArg(OPT_implib))
config->implib = arg->getValue();
- config->noimplib = args.hasArg(OPT_noimplib);
+ config->setNoimplib(args.hasArg(OPT_noimplib));
if (args.hasArg(OPT_profile))
doGC = true;
@@ -2091,11 +2091,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (!icfLevel)
icfLevel = doGC ? ICFLevel::All : ICFLevel::None;
- config->doGC = doGC;
+ config->setDoGC(doGC);
config->doICF = *icfLevel;
config->tailMerge =
(tailMerge == 1 && config->doICF != ICFLevel::None) || tailMerge == 2;
- config->ltoDebugPassManager = ltoDebugPM;
+ config->setLtoDebugPassManager(ltoDebugPM);
// Handle /lldsavetemps
if (args.hasArg(OPT_lldsavetemps)) {
@@ -2221,8 +2221,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
config->dtltoDistributor = args.getLastArgValue(OPT_thinlto_distributor);
// Handle /thinlto-distributor-arg:<arg>
- config->dtltoDistributorArgs =
- args::getStrings(args, OPT_thinlto_distributor_arg);
+ config->dtltoDistributorArgs.assign(
+ args::getStrings(args, OPT_thinlto_distributor_arg));
// Handle /thinlto-remote-compiler:<path>
config->dtltoCompiler = args.getLastArgValue(OPT_thinlto_remote_compiler);
@@ -2231,16 +2231,16 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
"/thinlto-distributor is specified.";
// Handle /thinlto-remote-compiler-prepend-arg:<arg>
- config->dtltoCompilerPrependArgs =
- args::getStrings(args, OPT_thinlto_remote_compiler_prepend_arg);
+ config->dtltoCompilerPrependArgs.assign(
+ args::getStrings(args, OPT_thinlto_remote_compiler_prepend_arg));
// Handle /thinlto-remote-compiler-arg:<arg>
- config->dtltoCompilerArgs =
- args::getStrings(args, OPT_thinlto_remote_compiler_arg);
+ config->dtltoCompilerArgs.assign(
+ args::getStrings(args, OPT_thinlto_remote_compiler_arg));
// Handle /fat-lto-objects
- config->fatLTOObjects =
- args.hasFlag(OPT_fat_lto_objects, OPT_fat_lto_objects_no, false);
+ config->setFatLTOObjects(
+ args.hasFlag(OPT_fat_lto_objects, OPT_fat_lto_objects_no, false));
// Handle /dwodir
config->dwoDir = args.getLastArgValue(OPT_dwodir);
@@ -2256,18 +2256,18 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
config->thinLTOObjectSuffixReplace =
getOldNewOptions(ctx, args, OPT_thinlto_object_suffix_replace);
config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path);
- config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
+ config->setLtoCSProfileGenerate(args.hasArg(OPT_lto_cs_profile_generate));
config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file);
config->ltoSampleProfileName = args.getLastArgValue(OPT_lto_sample_profile);
// Handle miscellaneous boolean flags.
- config->ltoPGOWarnMismatch = args.hasFlag(OPT_lto_pgo_warn_mismatch,
- OPT_lto_pgo_warn_mismatch_no, true);
+ config->setLtoPGOWarnMismatch(args.hasFlag(
+ OPT_lto_pgo_warn_mismatch, OPT_lto_pgo_warn_mismatch_no, true));
config->allowBind = args.hasFlag(OPT_allowbind, OPT_allowbind_no, true);
config->allowIsolation =
args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true);
config->incremental =
args.hasFlag(OPT_incremental, OPT_incremental_no,
- !config->doGC && config->doICF == ICFLevel::None &&
+ !config->getDoGC() && config->doICF == ICFLevel::None &&
!args.hasArg(OPT_order) && !args.hasArg(OPT_profile));
config->integrityCheck =
args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false);
@@ -2284,19 +2284,19 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
for (auto *arg : args.filtered(OPT_swaprun))
parseSwaprun(arg->getValue());
config->terminalServerAware =
- !config->dll && args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
+ !config->getDll() && args.hasFlag(OPT_tsaware, OPT_tsaware_no, true);
config->autoImport =
args.hasFlag(OPT_auto_import, OPT_auto_import_no, config->mingw);
config->pseudoRelocs = args.hasFlag(
OPT_runtime_pseudo_reloc, OPT_runtime_pseudo_reloc_no, config->mingw);
- config->callGraphProfileSort = args.hasFlag(
- OPT_call_graph_profile_sort, OPT_call_graph_profile_sort_no, true);
+ config->setCallGraphProfileSort(args.hasFlag(
+ OPT_call_graph_profile_sort, OPT_call_graph_profile_sort_no, true));
config->stdcallFixup =
args.hasFlag(OPT_stdcall_fixup, OPT_stdcall_fixup_no, config->mingw);
config->warnStdcallFixup = !args.hasArg(OPT_stdcall_fixup);
- config->allowDuplicateWeak =
- args.hasFlag(OPT_lld_allow_duplicate_weak,
- OPT_lld_allow_duplicate_weak_no, config->mingw);
+ config->setAllowDuplicateWeak(args.hasFlag(OPT_lld_allow_duplicate_weak,
+ OPT_lld_allow_duplicate_weak_no,
+ config->mingw));
if (args.hasFlag(OPT_inferasanlibs, OPT_inferasanlibs_no, false))
Warn(ctx) << "ignoring '/inferasanlibs', this flag is not supported";
@@ -2311,7 +2311,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
config->incremental = false;
}
- if (config->incremental && config->doGC) {
+ if (config->incremental && config->getDoGC()) {
Warn(ctx) << "ignoring '/incremental' because REF is enabled; use "
"'/opt:noref' to "
"disable";
@@ -2326,12 +2326,12 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
}
if (args.hasFlag(OPT_prefetch_inputs, OPT_prefetch_inputs_no, false))
- config->prefetchInputs = true;
+ config->setPrefetchInputs(true);
config->optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
config->optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
config->optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);
- config->optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
+ config->setOptRemarksWithHotness(args.hasArg(OPT_opt_remarks_with_hotness));
if (auto *arg = args.getLastArg(OPT_opt_remarks_hotness_threshold)) {
auto resultOrErr = remarks::parseHotnessThresholdOption(arg->getValue());
if (!resultOrErr)
@@ -2523,7 +2523,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Handle generation of import library from a def file.
if (!args.hasArg(OPT_INPUT, OPT_wholearchive_file)) {
ctx.forEachSymtab([](SymbolTable &symtab) { symtab.fixupExports(); });
- if (!config->noimplib)
+ if (!config->getNoimplib())
createImportLibrary(/*asLib=*/true);
return;
}
@@ -2584,7 +2584,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (config->outputFile.empty()) {
config->outputFile = getOutputPath(
(*args.filtered(OPT_INPUT, OPT_wholearchive_file).begin())->getValue(),
- config->dll, config->driver);
+ config->getDll(), config->driver);
}
// Fail early if an output file is not writable.
@@ -2601,7 +2601,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
for (auto *arg : args.filtered(OPT_map_info)) {
std::string s = StringRef(arg->getValue()).lower();
if (s == "exports")
- config->mapInfo = true;
+ config->setMapInfo(true);
else
Err(ctx) << "unknown option: /mapinfo:" << s;
}
@@ -2875,7 +2875,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
});
// Identify unreferenced COMDAT sections.
- if (config->doGC) {
+ if (config->getDoGC()) {
if (config->mingw) {
// markLive doesn't traverse .eh_frame, but the personality function is
// only reached that way. The proper solution would be to parse and
@@ -2925,11 +2925,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Windows specific -- when we are creating a .dll file, we also
// need to create a .lib file. In MinGW mode, we only do that when the
// -implib option is given explicitly, for compatibility with GNU ld.
- if (config->dll || !ctx.symtab.exports.empty() ||
+ if (config->getDll() || !ctx.symtab.exports.empty() ||
(ctx.config.machine == ARM64X && !ctx.hybridSymtab->exports.empty())) {
llvm::TimeTraceScope timeScope("Create .lib exports");
ctx.forEachActiveSymtab([](SymbolTable &symtab) { symtab.fixupExports(); });
- if (!config->noimplib && (!config->mingw || !config->implib.empty()))
+ if (!config->getNoimplib() && (!config->mingw || !config->implib.empty()))
createImportLibrary(/*asLib=*/false);
ctx.forEachActiveSymtab(
[](SymbolTable &symtab) { symtab.assignExportOrdinals(); });
@@ -2979,11 +2979,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (args.hasArg(OPT_call_graph_ordering_file))
Err(ctx) << "/order and /call-graph-order-file may not be used together";
parseOrderFile(arg->getValue());
- config->callGraphProfileSort = false;
+ config->setCallGraphProfileSort(false);
}
// Handle /call-graph-ordering-file and /call-graph-profile-sort (default on).
- if (config->callGraphProfileSort) {
+ if (config->getCallGraphProfileSort()) {
llvm::TimeTraceScope timeScope("Call graph");
if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file))
parseCallGraphFile(arg->getValue());
diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index 265ddee6d8557..6d3422891d5c7 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -328,7 +328,7 @@ void LinkerDriver::parseManifest(StringRef arg) {
// Results are directly written to Config.
void LinkerDriver::parseManifestUAC(StringRef arg) {
if (arg.equals_insensitive("no")) {
- ctx.config.manifestUAC = false;
+ ctx.config.setManifestUAC(false);
return;
}
for (;;) {
@@ -441,7 +441,7 @@ std::string LinkerDriver::createDefaultXml() {
os << "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
<< "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n"
<< " manifestVersion=\"1.0\">\n";
- if (ctx.config.manifestUAC) {
+ if (ctx.config.getManifestUAC()) {
os << " <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n"
<< " <security>\n"
<< " <requestedPrivileges>\n"
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index fd4858581ed54..7a1e314dfa186 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -87,7 +87,7 @@ static void checkAndSetWeakAlias(SymbolTable &symtab, InputFile *f,
// Weak aliases as produced by GCC are named in the form
// .weak.<weaksymbol>.<othersymbol>, where <othersymbol> is the name
// of another symbol emitted near the weak symbol.
- if (symtab.ctx.config.allowDuplicateWeak) {
+ if (symtab.ctx.config.getAllowDuplicateWeak()) {
auto isAbsZero = [](Symbol *sym) -> bool {
return isa<DefinedAbsolute>(sym) &&
dyn_cast<DefinedAbsolute>(sym)->getVA() == 0;
@@ -1228,7 +1228,7 @@ void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
ImportFile::ImportFile(COFFLinkerContext &ctx, MemoryBufferRef m)
: InputFile(ctx.getSymtab(getMachineType(m)), ImportKind, m),
- live(!ctx.config.doGC) {}
+ live(!ctx.config.getDoGC()) {}
MachineTypes ImportFile::getMachineType(MemoryBufferRef m) {
uint16_t machine =
diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index 0e335d647175c..8c813baaf71fd 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -88,16 +88,16 @@ lto::Config BitcodeCompiler::createConfig() {
assert(optLevelOrNone && "Invalid optimization level!");
c.CGOptLevel = *optLevelOrNone;
c.AlwaysEmitRegularLTOObj = !ctx.config.ltoObjPath.empty();
- c.DebugPassManager = ctx.config.ltoDebugPassManager;
+ c.DebugPassManager = ctx.config.getLtoDebugPassManager();
c.CSIRProfile = std::string(ctx.config.ltoCSProfileFile);
- c.RunCSIRInstr = ctx.config.ltoCSProfileGenerate;
- c.PGOWarnMismatch = ctx.config.ltoPGOWarnMismatch;
+ c.RunCSIRInstr = ctx.config.getLtoCSProfileGenerate();
+ c.PGOWarnMismatch = ctx.config.getLtoPGOWarnMismatch();
c.SampleProfile = ctx.config.ltoSampleProfileName;
c.TimeTraceEnabled = ctx.config.timeTraceEnabled;
c.TimeTraceGranularity = ctx.config.timeTraceGranularity;
c.RemarksFilename = ctx.config.optRemarksFilename;
c.RemarksPasses = ctx.config.optRemarksPasses;
- c.RemarksWithHotness = ctx.config.optRemarksWithHotness;
+ c.RemarksWithHotness = ctx.config.getOptRemarksWithHotness();
c.RemarksHotnessThreshold = ctx.config.optRemarksHotnessThreshold;
c.RemarksFormat = ctx.config.optRemarksFormat;
@@ -153,8 +153,10 @@ BitcodeCompiler::BitcodeCompiler(COFFLinkerContext &c) : ctx(c) {
llvm::lto::LTO::LTOKind::LTOK_Default, nullptr,
ctx.config.thinLTOEmitImportsFiles, ctx.config.thinLTOIndexOnly,
ctx.config.outputFile, ctx.config.dtltoDistributor,
- ctx.config.dtltoDistributorArgs, ctx.config.dtltoCompiler,
- ctx.config.dtltoCompilerPrependArgs, ctx.config.dtltoCompilerArgs,
+ ArrayRef<StringRef>(ctx.config.dtltoDistributorArgs),
+ ctx.config.dtltoCompiler,
+ ArrayRef<StringRef>(ctx.config.dtltoCompilerPrependArgs),
+ ArrayRef<StringRef>(ctx.config.dtltoCompilerArgs),
createAddBufferFn(files, file_names),
!ctx.config.saveTempsArgs.empty());
}
diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp
index 90ebacbe48d44..d1d6ffce065ff 100644
--- a/lld/COFF/MapFile.cpp
+++ b/lld/COFF/MapFile.cpp
@@ -319,7 +319,7 @@ void lld::coff::writeMapFile(COFFLinkerContext &ctx) {
os << staticSymStr[sym] << '\n';
// Print out the exported functions
- if (ctx.config.mapInfo) {
+ if (ctx.config.getMapInfo()) {
os << "\n";
os << " Exports\n";
os << "\n";
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index ea5bdbc0be489..61566f2e74f50 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -1120,7 +1120,7 @@ StringRef SymbolTable::findDefaultEntry() {
}
WindowsSubsystem SymbolTable::inferSubsystem() {
- if (ctx.config.dll)
+ if (ctx.config.getDll())
return IMAGE_SUBSYSTEM_WINDOWS_GUI;
if (ctx.config.mingw)
return IMAGE_SUBSYSTEM_WINDOWS_CUI;
diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp
index ba4f95d14bc64..a03c6b7033b1e 100644
--- a/lld/COFF/Symbols.cpp
+++ b/lld/COFF/Symbols.cpp
@@ -25,7 +25,7 @@ static_assert(sizeof(SymbolUnion) <= 48,
// Returns a symbol name for an error message.
std::string maybeDemangleSymbol(const COFFLinkerContext &ctx,
StringRef symName) {
- if (ctx.config.demangle) {
+ if (ctx.config.getDemangle()) {
std::string prefix;
StringRef prefixless = symName;
if (prefixless.consume_front("__imp_"))
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 3cab426df55cf..48e3c437836ea 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -1113,7 +1113,7 @@ void Writer::createSections() {
for (Chunk *c : ctx.driver.getChunks()) {
auto *sc = dyn_cast<SectionChunk>(c);
if (sc && !sc->live) {
- if (ctx.config.verbose)
+ if (ctx.config.getVerbose())
sc->printDiscardedMessage();
continue;
}
@@ -1888,7 +1888,7 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
coff->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
if (!config->is64())
coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
- if (config->dll)
+ if (config->getDll())
coff->Characteristics |= IMAGE_FILE_DLL;
if (config->driverUponly)
coff->Characteristics |= IMAGE_FILE_UP_SYSTEM_ONLY;
@@ -2797,7 +2797,7 @@ void Writer::sortCRTSectionChunks(std::vector<Chunk *> &chunks) {
};
llvm::stable_sort(chunks, sectionChunkOrder);
- if (ctx.config.verbose) {
+ if (ctx.config.getVerbose()) {
for (auto &c : chunks) {
auto sc = dyn_cast<SectionChunk>(c);
Log(ctx) << " " << sc->file->mb.getBufferIdentifier().str()
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 5d0c5dbd0065c..347ac7257fb25 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -375,7 +375,7 @@ void AArch64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
rs.handleTlsDesc(R_TLSDESC, R_GOT, type, offset, addend, sym);
continue;
case R_AARCH64_TLSDESC_CALL:
- if (!ctx.arg.shared)
+ if (!ctx.arg.getShared())
sec.addReloc({R_TPREL, type, offset, addend, &sym});
continue;
@@ -405,7 +405,7 @@ void AArch64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
rs.process(expr, type, offset, sym, addend);
}
- if (ctx.arg.branchToBranch)
+ if (ctx.arg.getBranchToBranch())
llvm::stable_sort(sec.relocs(),
[](auto &l, auto &r) { return l.offset < r.offset; });
}
@@ -841,7 +841,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
break;
case R_AARCH64_TLSLE_ADD_TPREL_HI12:
checkUInt(ctx, loc, val, 24, rel);
- if (ctx.arg.relax && (val >> 12) == 0) {
+ if (ctx.arg.getRelax() && (val >> 12) == 0) {
uint32_t inst = read32le(loc);
// The W-form zero-extends Xd, so only the X-form is a nop.
if ((inst & (1u << 31)) && (inst & 0x1f) == ((inst >> 5) & 0x1f)) {
@@ -985,7 +985,7 @@ void AArch64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
AArch64Relaxer::AArch64Relaxer(Ctx &ctx, ArrayRef<Relocation> relocs,
uint64_t secAddr, uint8_t *buf)
: ctx(ctx) {
- if (!ctx.arg.relax)
+ if (!ctx.arg.getRelax())
return;
// For a given symbol R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC
// relaxation is all-or-nothing. We can't relax only some of them, as there
@@ -1018,7 +1018,7 @@ bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel,
// to
// NOP
// ADR xn, sym
- if (!ctx.arg.relax || addRel.type != R_AARCH64_ADD_ABS_LO12_NC)
+ if (!ctx.arg.getRelax() || addRel.type != R_AARCH64_ADD_ABS_LO12_NC)
return false;
// Check if the relocations apply to consecutive instructions.
if (adrpRel.offset + 4 != addRel.offset)
@@ -1090,7 +1090,7 @@ bool AArch64Relaxer::isLegalAdrpLdrRelaxationCandidate(
// GOT references to absolute symbols can't be relaxed to use ADRP/ADD in
// position-independent code because these instructions produce a relative
// address.
- if (ctx.arg.isPic && !cast<Defined>(sym).section)
+ if (ctx.arg.getIsPic() && !cast<Defined>(sym).section)
return false;
// Check if the address difference is within 4GB range.
int64_t val =
@@ -1112,7 +1112,7 @@ bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel,
// ADRP xn, sym
// ADD xn, xn, :lo_12: sym
- if (!ctx.arg.relax || adrpRel.type != R_AARCH64_ADR_GOT_PAGE ||
+ if (!ctx.arg.getRelax() || adrpRel.type != R_AARCH64_ADR_GOT_PAGE ||
ldrRel.type != R_AARCH64_LD64_GOT_LO12_NC)
return false;
@@ -1343,7 +1343,7 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
// PAuthABI, which requires v8.3-A, we can use the non-hint space
// instructions.
- if (ctx.arg.zPacPlt) {
+ if (ctx.arg.getZPacPlt()) {
if (ctx.aarch64PauthAbiCoreInfo && ctx.aarch64PauthAbiCoreInfo->isValid())
pacEntryKind = PEK_Auth;
else
@@ -1553,7 +1553,7 @@ void elf::createTaggedSymbols(Ctx &ctx) {
void elf::setAArch64TargetInfo(Ctx &ctx) {
if ((ctx.arg.andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ||
- ctx.arg.zPacPlt)
+ ctx.arg.getZPacPlt())
ctx.target.reset(new AArch64BtiPac(ctx));
else
ctx.target.reset(new AArch64(ctx));
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index e1f73b991f1f3..a47642f6d5a47 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -133,7 +133,7 @@ uint32_t ARM::calcEFlags() const {
else if (ctx.arg.armVFPArgs == ARMVFPArgKind::VFP)
abiFloatType = EF_ARM_ABI_FLOAT_HARD;
- if (!ctx.arg.isLE && ctx.arg.armBe8)
+ if (!ctx.arg.getIsLE() && ctx.arg.getArmBe8())
armBE8 = EF_ARM_BE8;
// We don't currently use any features incompatible with EF_ARM_EABI_VER5,
@@ -273,7 +273,7 @@ void ARM::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
// Platform-specific relocations:
case R_ARM_TARGET1:
- expr = ctx.arg.target1Rel ? R_PC : R_ABS;
+ expr = ctx.arg.getTarget1Rel() ? R_PC : R_ABS;
break;
case R_ARM_TARGET2:
if (ctx.arg.target2 == Target2Policy::Rel)
@@ -315,7 +315,8 @@ void ARM::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
}
RelType ARM::getDynRel(RelType type) const {
- if ((type == R_ARM_ABS32) || (type == R_ARM_TARGET1 && !ctx.arg.target1Rel))
+ if ((type == R_ARM_ABS32) ||
+ (type == R_ARM_TARGET1 && !ctx.arg.getTarget1Rel()))
return R_ARM_ABS32;
return R_ARM_NONE;
}
@@ -1399,7 +1400,7 @@ void elf::processArmCmseSymbols(Ctx &ctx) {
continue;
// If input object build attributes do not support CMSE, error and disable
// further scanning for <sym>, __acle_se_<sym> pairs.
- if (!ctx.arg.armCMSESupport) {
+ if (!ctx.arg.getArmCMSESupport()) {
Err(ctx) << "CMSE is only supported by ARMv8-M architecture or later";
ctx.arg.cmseImplib = false;
break;
@@ -1621,7 +1622,7 @@ template <typename ELFT> void elf::writeARMCmseImportLib(Ctx &ctx) {
eHdr->e_entry = 0;
eHdr->e_shoff = sectionHeaderOff;
eHdr->e_ident[EI_CLASS] = ELFCLASS32;
- eHdr->e_ident[EI_DATA] = ctx.arg.isLE ? ELFDATA2LSB : ELFDATA2MSB;
+ eHdr->e_ident[EI_DATA] = ctx.arg.getIsLE() ? ELFDATA2LSB : ELFDATA2MSB;
eHdr->e_ident[EI_VERSION] = EV_CURRENT;
eHdr->e_ident[EI_OSABI] = ctx.arg.osabi;
eHdr->e_ident[EI_ABIVERSION] = 0;
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 6c65b74b716f2..3ec9c2fb12a65 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -40,7 +40,7 @@ class LoongArch final : public TargetInfo {
template <class ELFT, class RelTy>
void scanSectionImpl(InputSectionBase &, Relocs<RelTy>, unsigned shard);
void scanSection(InputSectionBase &sec, unsigned shard) override {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
elf::scanSection1<LoongArch, ELF64LE>(*this, sec, shard);
else
elf::scanSection1<LoongArch, ELF32LE>(*this, sec, shard);
@@ -233,7 +233,7 @@ LoongArch::LoongArch(Ctx &ctx) : TargetInfo(ctx) {
relativeRel = R_LARCH_RELATIVE;
iRelativeRel = R_LARCH_IRELATIVE;
- if (ctx.arg.is64) {
+ if (ctx.arg.getIs64()) {
symbolicRel = R_LARCH_64;
tlsModuleIndexRel = R_LARCH_TLS_DTPMOD64;
tlsOffsetRel = R_LARCH_TLS_DTPREL64;
@@ -258,7 +258,7 @@ LoongArch::LoongArch(Ctx &ctx) : TargetInfo(ctx) {
}
static uint32_t getEFlags(Ctx &ctx, const InputFile *f) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader().e_flags;
return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader().e_flags;
}
@@ -338,7 +338,7 @@ int64_t LoongArch::getImplicitAddend(const uint8_t *buf, RelType type) const {
return read64le(buf);
case R_LARCH_RELATIVE:
case R_LARCH_IRELATIVE:
- return ctx.arg.is64 ? read64le(buf) : read32le(buf);
+ return ctx.arg.getIs64() ? read64le(buf) : read32le(buf);
case R_LARCH_NONE:
case R_LARCH_JUMP_SLOT:
// These relocations are defined as not having an implicit addend.
@@ -351,7 +351,7 @@ int64_t LoongArch::getImplicitAddend(const uint8_t *buf, RelType type) const {
}
void LoongArch::writeGotPlt(uint8_t *buf, const Symbol &s) const {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write64le(buf, ctx.in.plt->getVA());
else
write32le(buf, ctx.in.plt->getVA());
@@ -359,7 +359,7 @@ void LoongArch::writeGotPlt(uint8_t *buf, const Symbol &s) const {
void LoongArch::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
if (ctx.arg.writeAddends) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write64le(buf, s.getVA(ctx));
else
write32le(buf, s.getVA(ctx));
@@ -386,17 +386,17 @@ void LoongArch::writePltHeader(uint8_t *buf) const {
// ld.[wd] $t0, $t0, Wordsize ; t0 = link_map
// jr $t3
uint32_t offset = ctx.in.gotPlt->getVA() - ctx.in.plt->getVA();
- uint32_t sub = ctx.arg.is64 ? SUB_D : SUB_W;
- uint32_t ld = ctx.arg.is64 ? LD_D : LD_W;
- uint32_t addi = ctx.arg.is64 ? ADDI_D : ADDI_W;
- uint32_t srli = ctx.arg.is64 ? SRLI_D : SRLI_W;
+ uint32_t sub = ctx.arg.getIs64() ? SUB_D : SUB_W;
+ uint32_t ld = ctx.arg.getIs64() ? LD_D : LD_W;
+ uint32_t addi = ctx.arg.getIs64() ? ADDI_D : ADDI_W;
+ uint32_t srli = ctx.arg.getIs64() ? SRLI_D : SRLI_W;
write32le(buf + 0, insn(PCADDU12I, R_T2, hi20(offset), 0));
write32le(buf + 4, insn(sub, R_T1, R_T1, R_T3));
write32le(buf + 8, insn(ld, R_T3, R_T2, lo12(offset)));
write32le(buf + 12,
insn(addi, R_T1, R_T1, lo12(-ctx.target->pltHeaderSize - 12)));
write32le(buf + 16, insn(addi, R_T0, R_T2, lo12(offset)));
- write32le(buf + 20, insn(srli, R_T1, R_T1, ctx.arg.is64 ? 1 : 2));
+ write32le(buf + 20, insn(srli, R_T1, R_T1, ctx.arg.getIs64() ? 1 : 2));
write32le(buf + 24, insn(ld, R_T0, R_T0, ctx.arg.wordsize));
write32le(buf + 28, insn(JIRL, R_ZERO, R_T3, 0));
}
@@ -413,7 +413,7 @@ void LoongArch::writePlt(uint8_t *buf, const Symbol &sym,
uint32_t offset = sym.getGotPltVA(ctx) - pltEntryAddr;
write32le(buf + 0, insn(PCADDU12I, R_T3, hi20(offset), 0));
write32le(buf + 4,
- insn(ctx.arg.is64 ? LD_D : LD_W, R_T3, R_T3, lo12(offset)));
+ insn(ctx.arg.getIs64() ? LD_D : LD_W, R_T3, R_T3, lo12(offset)));
write32le(buf + 8, insn(JIRL, R_T1, R_T3, 0));
write32le(buf + 12, insn(ANDI, R_ZERO, R_ZERO, 0));
}
@@ -679,7 +679,7 @@ void LoongArch::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
addend, sym);
continue;
case R_LARCH_TLS_DESC_CALL:
- if (!ctx.arg.shared)
+ if (!ctx.arg.getShared())
sec.addReloc(
{sym.isPreemptible ? R_GOT : R_TPREL, type, offset, addend, &sym});
continue;
@@ -702,7 +702,7 @@ void LoongArch::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
// Relaxation hints:
case R_LARCH_TLS_LE_ADD_R:
case R_LARCH_RELAX:
- if (ctx.arg.relax)
+ if (ctx.arg.getRelax())
sec.addReloc({R_RELAX_HINT, type, offset, addend, &sym});
continue;
case R_LARCH_ALIGN:
@@ -1081,8 +1081,8 @@ bool LoongArch::synthesizeAlignAux(uint64_t &dot, InputSection *sec) {
// output relocation section is updated with all the newly synthesized ALIGN
// relocations.
bool LoongArch::synthesizeAlign(uint64_t &dot, InputSection *sec) {
- assert(ctx.arg.relocatable);
- if (ctx.arg.is64)
+ assert(ctx.arg.getRelocatable());
+ if (ctx.arg.getIs64())
return synthesizeAlignAux<ELF64LE>(dot, sec);
return synthesizeAlignAux<ELF32LE>(dot, sec);
}
@@ -1137,7 +1137,7 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
if (rHi20.type == R_LARCH_GOT_PC_HI20 &&
(!rHi20.sym || rHi20.sym != rLo12.sym || !rHi20.sym->isDefined() ||
rHi20.sym->isPreemptible || rHi20.sym->isGnuIFunc() ||
- (ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section) ||
+ (ctx.arg.getIsPic() && !cast<Defined>(*rHi20.sym).section) ||
rHi20.addend != 0 || rLo12.addend != 0))
return;
@@ -1450,7 +1450,7 @@ void LoongArch::tlsdescToIe(uint8_t *loc, const Relocation &rel,
relocateNoSym(loc, R_LARCH_TLS_IE_PC_HI20, val);
break;
case R_LARCH_TLS_DESC_CALL:
- write32le(loc, insn(ctx.arg.is64 ? LD_D : LD_W, R_A0, R_A0,
+ write32le(loc, insn(ctx.arg.getIs64() ? LD_D : LD_W, R_A0, R_A0,
0)); // ld.[wd] $a0, $a0, %ie_pc_lo12
relocateNoSym(loc, R_LARCH_TLS_IE_PC_LO12, val);
break;
@@ -1522,7 +1522,7 @@ bool LoongArch::tryGotToPCRel(uint8_t *loc, const Relocation &rHi20,
// GOT references to absolute symbols can't be relaxed to use PCALAU12I/ADDI
// in position-independent code because these instructions produce a relative
// address.
- if ((ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section))
+ if ((ctx.arg.getIsPic() && !cast<Defined>(*rHi20.sym).section))
return false;
// Check if the addends of the both relocations are zero.
@@ -1531,7 +1531,7 @@ bool LoongArch::tryGotToPCRel(uint8_t *loc, const Relocation &rHi20,
const uint32_t currInsn = read32le(loc);
const uint32_t nextInsn = read32le(loc + 4);
- const uint32_t ldOpcode = ctx.arg.is64 ? LD_D : LD_W;
+ const uint32_t ldOpcode = ctx.arg.getIs64() ? LD_D : LD_W;
// Check if the first instruction is PCALAU12I and the second instruction is
// LD.
if ((currInsn & 0xfe000000) != PCALAU12I ||
@@ -1562,7 +1562,7 @@ bool LoongArch::tryGotToPCRel(uint8_t *loc, const Relocation &rHi20,
write32le(loc, insn(PCALAU12I, getD5(currInsn), 0, 0));
relocate(loc, newRHi20, pageDelta);
// addi.w/d $a0, $a0, %pc_lo12
- write32le(loc + 4, insn(ctx.arg.is64 ? ADDI_D : ADDI_W, getD5(nextInsn),
+ write32le(loc + 4, insn(ctx.arg.getIs64() ? ADDI_D : ADDI_W, getD5(nextInsn),
getJ5(nextInsn), 0));
relocate(loc + 4, newRLo12, SignExtend64(symLocal, 64));
return true;
@@ -1601,7 +1601,7 @@ static bool pairForGotRels(ArrayRef<Relocation> relocs) {
}
void LoongArch::relocateAlloc(InputSection &sec, uint8_t *buf) const {
- const unsigned bits = ctx.arg.is64 ? 64 : 32;
+ const unsigned bits = ctx.arg.getIs64() ? 64 : 32;
uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff;
bool isExtreme = false;
const MutableArrayRef<Relocation> relocs = sec.relocs();
diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp
index 308a0f75e588d..500e3fc47db7e 100644
--- a/lld/ELF/Arch/Mips.cpp
+++ b/lld/ELF/Arch/Mips.cpp
@@ -126,7 +126,7 @@ template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
}
template <class ELFT> void MIPS<ELFT>::initTargetSpecificSections() {
- if (!ctx.arg.shared && ctx.hasDynsym) {
+ if (!ctx.arg.getShared() && ctx.getHasDynsym()) {
ctx.in.mipsRldMap = std::make_unique<RldMapSection>(ctx);
ctx.inputSections.push_back(ctx.in.mipsRldMap.get());
}
@@ -373,7 +373,7 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
write32(ctx, buf + 20, 0x0018c082); // srl $24, $24, 2
}
- uint32_t jalrInst = ctx.arg.zHazardplt ? 0x0320fc09 : 0x0320f809;
+ uint32_t jalrInst = ctx.arg.getZHazardplt() ? 0x0320fc09 : 0x0320f809;
write32(ctx, buf + 24, jalrInst); // jalr.hb $25 or jalr $25
write32(ctx, buf + 28, 0x2718fffe); // subu $24, $24, 2
@@ -409,8 +409,8 @@ void MIPS<ELFT>::writePlt(uint8_t *buf, const Symbol &sym,
uint32_t loadInst = ELFT::Is64Bits ? 0xddf90000 : 0x8df90000;
uint32_t jrInst = isMipsR6(ctx)
- ? (ctx.arg.zHazardplt ? 0x03200409 : 0x03200009)
- : (ctx.arg.zHazardplt ? 0x03200408 : 0x03200008);
+ ? (ctx.arg.getZHazardplt() ? 0x03200409 : 0x03200009)
+ : (ctx.arg.getZHazardplt() ? 0x03200408 : 0x03200008);
uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;
write32(ctx, buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
@@ -533,7 +533,7 @@ int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
case (R_MIPS_64 << 8) | R_MIPS_REL32:
return read64(ctx, buf);
case R_MIPS_COPY:
- return ctx.arg.is64 ? read64(ctx, buf) : read32(ctx, buf);
+ return ctx.arg.getIs64() ? read64(ctx, buf) : read32(ctx, buf);
case R_MIPS_NONE:
case R_MIPS_JUMP_SLOT:
case R_MIPS_JALR:
@@ -639,7 +639,7 @@ static RelType getMipsN32RelType(Ctx &ctx, RelTy *&rel, RelTy *end) {
uint64_t offset = rel->r_offset;
int n = 0;
while (rel != end && rel->r_offset == offset)
- type |= (rel++)->getType(ctx.arg.isMips64EL) << (8 * n++);
+ type |= (rel++)->getType(ctx.arg.getIsMips64EL()) << (8 * n++);
return type;
}
@@ -679,18 +679,18 @@ void MIPS<ELFT>::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
const RelTy &rel = *it;
uint64_t offset = rel.r_offset;
if constexpr (ELFT::Is64Bits) {
- type = it->getType(ctx.arg.isMips64EL);
+ type = it->getType(ctx.arg.getIsMips64EL());
++it;
} else {
if (ctx.arg.mipsN32Abi) {
type = getMipsN32RelType(ctx, it, rels.end());
} else {
- type = it->getType(ctx.arg.isMips64EL);
+ type = it->getType(ctx.arg.getIsMips64EL());
++it;
}
}
- uint32_t symIdx = rel.getSymbol(ctx.arg.isMips64EL);
+ uint32_t symIdx = rel.getSymbol(ctx.arg.getIsMips64EL());
Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIdx);
RelExpr expr = getRelExpr(type, sym, sec.content().data() + rel.r_offset);
if (expr == R_NONE)
@@ -714,8 +714,8 @@ void MIPS<ELFT>::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
// the relocation table, so we need to do linear search. *sigh*
bool found = false;
for (auto *ri = &rel; ri != rels.end(); ++ri) {
- if (ri->getType(ctx.arg.isMips64EL) == pairTy &&
- ri->getSymbol(ctx.arg.isMips64EL) == symIdx) {
+ if (ri->getType(ctx.arg.getIsMips64EL()) == pairTy &&
+ ri->getSymbol(ctx.arg.getIsMips64EL()) == symIdx) {
addend += getImplicitAddend(buf + ri->r_offset, pairTy);
found = true;
break;
@@ -793,7 +793,7 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
// The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
// is updated addend (not a GOT index). In that case write high 16 bits
// to store a correct addend value.
- if (ctx.arg.relocatable) {
+ if (ctx.arg.getRelocatable()) {
writeValue(ctx, loc, val + 0x8000, 16, 16);
} else {
checkInt(ctx, loc, val, 16, rel);
@@ -801,7 +801,7 @@ void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
}
break;
case R_MICROMIPS_GOT16:
- if (ctx.arg.relocatable) {
+ if (ctx.arg.getRelocatable()) {
writeShuffle<e>(ctx, loc, val + 0x8000, 16, 16);
} else {
checkInt(ctx, loc, val, 16, rel);
@@ -1058,7 +1058,7 @@ template <class ELFT> void OptionsSection<ELFT>::writeTo(uint8_t *buf) {
options->kind = ODK_REGINFO;
options->size = getSize();
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
reginfo.ri_gp_value = ctx.in.mipsGot->getGp();
memcpy(buf + sizeof(Elf_Mips_Options), ®info, sizeof(reginfo));
}
@@ -1090,7 +1090,7 @@ ReginfoSection<ELFT>::ReginfoSection(Ctx &ctx)
}
template <class ELFT> void ReginfoSection<ELFT>::writeTo(uint8_t *buf) {
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
reginfo.ri_gp_value = ctx.in.mipsGot->getGp();
memcpy(buf, ®info, sizeof(reginfo));
}
diff --git a/lld/ELF/Arch/MipsArchTree.cpp b/lld/ELF/Arch/MipsArchTree.cpp
index 9158859045087..7172ff47e9759 100644
--- a/lld/ELF/Arch/MipsArchTree.cpp
+++ b/lld/ELF/Arch/MipsArchTree.cpp
@@ -69,7 +69,7 @@ static void checkFlags(Ctx &ctx, ArrayRef<FileFlags> files) {
bool fp = files[0].flags & EF_MIPS_FP64;
for (const FileFlags &f : files) {
- if (ctx.arg.is64 && f.flags & EF_MIPS_MICROMIPS)
+ if (ctx.arg.getIs64() && f.flags & EF_MIPS_MICROMIPS)
Err(ctx) << f.file << ": microMIPS 64-bit is not supported";
uint32_t abi2 = f.flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
@@ -299,7 +299,7 @@ template <class ELFT> uint32_t elf::calcMipsEFlags(Ctx &ctx) {
// If we don't have any input files, we'll have to rely on the information
// we can derive from emulation information, since this at least gets us
// ABI.
- if (ctx.arg.emulation.empty() || ctx.arg.is64)
+ if (ctx.arg.emulation.empty() || ctx.arg.getIs64())
return 0;
return ctx.arg.mipsN32Abi ? EF_MIPS_ABI2 : EF_MIPS_ABI_O32;
}
diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp
index e09ecb5c2cff6..8053f5ec774a2 100644
--- a/lld/ELF/Arch/PPC.cpp
+++ b/lld/ELF/Arch/PPC.cpp
@@ -77,18 +77,18 @@ static uint16_t lo(uint32_t v) { return v; }
static uint16_t ha(uint32_t v) { return (v + 0x8000) >> 16; }
static uint32_t readFromHalf16(Ctx &ctx, const uint8_t *loc) {
- return read32(ctx, ctx.arg.isLE ? loc : loc - 2);
+ return read32(ctx, ctx.arg.getIsLE() ? loc : loc - 2);
}
static void writeFromHalf16(Ctx &ctx, uint8_t *loc, uint32_t insn) {
- write32(ctx, ctx.arg.isLE ? loc : loc - 2, insn);
+ write32(ctx, ctx.arg.getIsLE() ? loc : loc - 2, insn);
}
void elf::writePPC32GlinkSection(Ctx &ctx, uint8_t *buf, size_t numEntries) {
// Create canonical PLT entries for non-PIE code. Compilers don't generate
// non-GOT-non-PLT relocations referencing external functions for -fpie/-fPIE.
uint32_t glink = ctx.in.plt->getVA(); // VA of .glink
- if (!ctx.arg.isPic) {
+ if (!ctx.arg.getIsPic()) {
for (const Symbol *sym :
cast<PPC32GlinkSection>(*ctx.in.plt).canonical_plts) {
writePPC32PltCallStub(ctx, buf, glink, sym->getGotPltVA(ctx), nullptr, 0);
@@ -116,7 +116,7 @@ void elf::writePPC32GlinkSection(Ctx &ctx, uint8_t *buf, size_t numEntries) {
// itself) and calls _dl_runtime_resolve() (in glibc).
uint32_t got = ctx.in.got->getVA();
const uint8_t *end = buf + 64;
- if (ctx.arg.isPic) {
+ if (ctx.arg.getIsPic()) {
uint32_t afterBcl = 4 * ctx.in.plt->getNumEntries() + 12;
uint32_t gotBcl = got + 4 - (glink + afterBcl);
write32(ctx, buf + 0,
@@ -179,7 +179,7 @@ PPC::PPC(Ctx &ctx) : TargetInfo(ctx) {
gotPltHeaderEntriesNum = 0;
pltHeaderSize = 0;
pltEntrySize = 4;
- ipltEntrySize = ctx.arg.isPic ? 32 : 16;
+ ipltEntrySize = ctx.arg.getIsPic() ? 32 : 16;
needsThunks = true;
@@ -367,7 +367,7 @@ void PPC::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
rs.handleTlsIe(R_GOT_OFF, type, offset, addend, sym);
continue;
case R_PPC_TLS:
- if (!ctx.arg.shared && !sym.isPreemptible)
+ if (!ctx.arg.getShared() && !sym.isPreemptible)
sec.addReloc({R_TPREL, type, offset, addend, &sym});
continue;
@@ -378,7 +378,7 @@ void PPC::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
continue;
case R_PPC_TLSGD:
case R_PPC_TLSLD:
- if (!ctx.arg.shared) {
+ if (!ctx.arg.getShared()) {
sec.addReloc({sym.isPreemptible ? R_GOT_OFF : R_TPREL, type, offset,
addend, &sym});
++it; // Skip REL24
@@ -408,7 +408,7 @@ void PPC::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
}
void PPC::scanSection(InputSectionBase &sec, unsigned shard) {
- if (ctx.arg.isLE)
+ if (ctx.arg.getIsLE())
elf::scanSection1<PPC, ELF32LE>(*this, sec, shard);
else
elf::scanSection1<PPC, ELF32BE>(*this, sec, shard);
diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index 17ee2f723e7b2..291e463bc5e2a 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -247,7 +247,7 @@ unsigned elf::getPPC64GlobalEntryToLocalEntryOffset(Ctx &ctx, uint8_t stOther) {
}
void elf::writePrefixedInst(Ctx &ctx, uint8_t *loc, uint64_t insn) {
- insn = ctx.arg.isLE ? insn << 32 | insn >> 32 : insn;
+ insn = ctx.arg.getIsLE() ? insn << 32 | insn >> 32 : insn;
write64(ctx, loc, insn);
}
@@ -380,7 +380,7 @@ getRelaTocSymAndAddend(InputSectionBase *tocSec, uint64_t offset) {
// Returns true if the relaxation is performed.
static bool tryRelaxPPC64TocIndirection(Ctx &ctx, const Relocation &rel,
uint8_t *bufLoc) {
- assert(ctx.arg.tocOptimize);
+ assert(ctx.arg.getTocOptimize());
if (rel.addend < 0)
return false;
@@ -393,8 +393,8 @@ static bool tryRelaxPPC64TocIndirection(Ctx &ctx, const Relocation &rel,
int64_t addend;
auto *tocISB = cast<InputSectionBase>(defSym->section);
std::tie(d, addend) =
- ctx.arg.isLE ? getRelaTocSymAndAddend<ELF64LE>(tocISB, rel.addend)
- : getRelaTocSymAndAddend<ELF64BE>(tocISB, rel.addend);
+ ctx.arg.getIsLE() ? getRelaTocSymAndAddend<ELF64LE>(tocISB, rel.addend)
+ : getRelaTocSymAndAddend<ELF64BE>(tocISB, rel.addend);
// Only non-preemptable defined symbols can be relaxed.
if (!d || d->isPreemptible)
@@ -567,16 +567,16 @@ static int64_t getTotalDisp(uint64_t prefixedInsn, uint32_t accessInsn) {
// little-endian it is pointing to the start of the word. These 2 helpers are to
// simplify reading and writing in that context.
static void writeFromHalf16(Ctx &ctx, uint8_t *loc, uint32_t insn) {
- write32(ctx, ctx.arg.isLE ? loc : loc - 2, insn);
+ write32(ctx, ctx.arg.getIsLE() ? loc : loc - 2, insn);
}
static uint32_t readFromHalf16(Ctx &ctx, const uint8_t *loc) {
- return read32(ctx, ctx.arg.isLE ? loc : loc - 2);
+ return read32(ctx, ctx.arg.getIsLE() ? loc : loc - 2);
}
static uint64_t readPrefixedInst(Ctx &ctx, const uint8_t *loc) {
uint64_t fullInstr = read64(ctx, loc);
- return ctx.arg.isLE ? (fullInstr << 32 | fullInstr >> 32) : fullInstr;
+ return ctx.arg.getIsLE() ? (fullInstr << 32 | fullInstr >> 32) : fullInstr;
}
PPC64::PPC64(Ctx &ctx) : TargetInfo(ctx) {
@@ -1119,7 +1119,7 @@ void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
RelocScan rs(ctx, &sec, shard);
sec.relocations.reserve(rels.size());
bool optimizeTlsGdLd =
- !missingTlsGdLdMarker<RelTy>(sec, rels) && !ctx.arg.shared;
+ !missingTlsGdLdMarker<RelTy>(sec, rels) && !ctx.arg.getShared();
for (auto it = rels.begin(); it != rels.end(); ++it) {
RelType type = it->getType(false);
uint32_t symIdx = it->getSymbol(false);
@@ -1129,7 +1129,7 @@ void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
rs.maybeReportUndefined(cast<Undefined>(sym), offset))
continue;
int64_t addend = rs.getAddend<ELFT>(*it, type);
- if (ctx.arg.isPic && type == R_PPC64_TOC)
+ if (ctx.arg.getIsPic() && type == R_PPC64_TOC)
addend += getPPC64TocBase(ctx);
RelExpr expr;
@@ -1188,7 +1188,7 @@ void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
// TOC-relative relocations:
case R_PPC64_TOC16:
case R_PPC64_TOC16_DS:
- sec.file->ppc64SmallCodeModelTocRelocs = true;
+ sec.file->setPpc64SmallCodeModelTocRelocs(true);
expr = R_GOTREL;
break;
case R_PPC64_TOC16_HI:
@@ -1250,7 +1250,7 @@ void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
rs.handleTlsIe(R_GOT_PC, type, offset, addend, sym);
continue;
case R_PPC64_TLS:
- if (!ctx.arg.shared && !sym.isPreemptible)
+ if (!ctx.arg.getShared() && !sym.isPreemptible)
sec.addReloc({R_TPREL, type, offset, addend, &sym});
continue;
@@ -1354,7 +1354,7 @@ void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
}
void PPC64::scanSection(InputSectionBase &sec, unsigned shard) {
- if (ctx.arg.isLE)
+ if (ctx.arg.getIsLE())
elf::scanSection1<PPC64, ELF64LE>(*this, sec, shard);
else
elf::scanSection1<PPC64, ELF64BE>(*this, sec, shard);
@@ -1466,7 +1466,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
case R_PPC64_ADDR16_HA:
case R_PPC64_REL16_HA:
case R_PPC64_TPREL16_HA:
- if (ctx.arg.tocOptimize && shouldTocOptimize && ha(val) == 0)
+ if (ctx.arg.getTocOptimize() && shouldTocOptimize && ha(val) == 0)
writeFromHalf16(ctx, loc, NOP);
else {
checkInt(ctx, loc, val + 0x8000, 32, rel);
@@ -1532,7 +1532,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
// When the high-adjusted part of a toc relocation evaluates to 0, it is
// changed into a nop. The lo part then needs to be updated to use the
// toc-pointer register r2, as the base register.
- if (ctx.arg.tocOptimize && shouldTocOptimize && ha(val) == 0) {
+ if (ctx.arg.getTocOptimize() && shouldTocOptimize && ha(val) == 0) {
uint32_t insn = readFromHalf16(ctx, loc);
if (isInstructionUpdateForm(insn))
Err(ctx) << getErrorLoc(ctx, loc)
@@ -1557,7 +1557,7 @@ void PPC64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
uint32_t insn = readFromHalf16(ctx, loc);
uint16_t mask = isDQFormInstruction(insn) ? 0xf : 0x3;
checkAlignment(ctx, loc, lo(val), mask + 1, rel);
- if (ctx.arg.tocOptimize && shouldTocOptimize && ha(val) == 0) {
+ if (ctx.arg.getTocOptimize() && shouldTocOptimize && ha(val) == 0) {
// When the high-adjusted part of a toc relocation evaluates to 0, it is
// changed into a nop. The lo part then needs to be updated to use the toc
// pointer register r2, as the base register.
@@ -1682,7 +1682,7 @@ bool PPC64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
RelExpr PPC64::adjustGotPcExpr(RelType type, int64_t addend,
const uint8_t *loc) const {
if ((type == R_PPC64_GOT_PCREL34 || type == R_PPC64_PCREL_OPT) &&
- ctx.arg.pcRelOptimize) {
+ ctx.arg.getPcRelOptimize()) {
// It only makes sense to optimize pld since paddi means that the address
// of the object in the GOT is required rather than the object itself.
if ((readPrefixedInst(ctx, loc) & 0xfc000000) == 0xe4000000)
@@ -1789,7 +1789,7 @@ void PPC64::relocateAlloc(InputSection &sec, uint8_t *buf) const {
// entry, there may be R_PPC64_TOC16_HA not paired with
// R_PPC64_TOC16_LO_DS. Don't relax. This loses some relaxation
// opportunities but is safe.
- if (ctx.arg.tocOptimize &&
+ if (ctx.arg.getTocOptimize() &&
!ctx.ppc64noTocRelax.contains({rel.sym, rel.addend}) &&
tryRelaxPPC64TocIndirection(ctx, rel, loc))
continue;
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 13c919c195e2e..4c55e324709ee 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -133,7 +133,7 @@ RISCV::RISCV(Ctx &ctx) : TargetInfo(ctx) {
pltRel = R_RISCV_JUMP_SLOT;
relativeRel = R_RISCV_RELATIVE;
iRelativeRel = R_RISCV_IRELATIVE;
- if (ctx.arg.is64) {
+ if (ctx.arg.getIs64()) {
symbolicRel = R_RISCV_64;
tlsModuleIndexRel = R_RISCV_TLS_DTPMOD64;
tlsOffsetRel = R_RISCV_TLS_DTPREL64;
@@ -159,7 +159,7 @@ RISCV::RISCV(Ctx &ctx) : TargetInfo(ctx) {
}
static uint32_t getEFlags(Ctx &ctx, InputFile *f) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader().e_flags;
return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader().e_flags;
}
@@ -206,25 +206,25 @@ int64_t RISCV::getImplicitAddend(const uint8_t *buf, RelType type) const {
return read64le(buf);
case R_RISCV_RELATIVE:
case R_RISCV_IRELATIVE:
- return ctx.arg.is64 ? read64le(buf) : read32le(buf);
+ return ctx.arg.getIs64() ? read64le(buf) : read32le(buf);
case R_RISCV_NONE:
case R_RISCV_JUMP_SLOT:
// These relocations are defined as not having an implicit addend.
return 0;
case R_RISCV_TLSDESC:
- return ctx.arg.is64 ? read64le(buf + 8) : read32le(buf + 4);
+ return ctx.arg.getIs64() ? read64le(buf + 8) : read32le(buf + 4);
}
}
void RISCV::writeGotHeader(uint8_t *buf) const {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write64le(buf, ctx.in.dynamic->getVA());
else
write32le(buf, ctx.in.dynamic->getVA());
}
void RISCV::writeGotPlt(uint8_t *buf, const Symbol &s) const {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write64le(buf, ctx.in.plt->getVA());
else
write32le(buf, ctx.in.plt->getVA());
@@ -232,7 +232,7 @@ void RISCV::writeGotPlt(uint8_t *buf, const Symbol &s) const {
void RISCV::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
if (ctx.arg.writeAddends) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write64le(buf, s.getVA(ctx));
else
write32le(buf, s.getVA(ctx));
@@ -264,7 +264,7 @@ void RISCV::writePltHeader(uint8_t *buf) const {
bool lpad =
ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED;
uint32_t offset = ctx.in.gotPlt->getVA() - ctx.in.plt->getVA();
- uint32_t load = ctx.arg.is64 ? LD : LW;
+ uint32_t load = ctx.arg.getIs64() ? LD : LW;
uint32_t auipcReg = lpad ? X_T3 : X_T2;
uint32_t workReg = lpad ? X_T2 : X_T3;
@@ -274,7 +274,7 @@ void RISCV::writePltHeader(uint8_t *buf) const {
write32le(buf + 12, itype(ADDI, X_T1, X_T1,
-ctx.target->pltHeaderSize - (lpad ? 16 : 12)));
write32le(buf + 16, itype(ADDI, X_T0, auipcReg, lo12(offset)));
- write32le(buf + 20, itype(SRLI, X_T1, X_T1, ctx.arg.is64 ? 1 : 2));
+ write32le(buf + 20, itype(SRLI, X_T1, X_T1, ctx.arg.getIs64() ? 1 : 2));
write32le(buf + 24, itype(load, X_T0, X_T0, ctx.arg.wordsize));
write32le(buf + 28, itype(JALR, X_X0, workReg, 0));
}
@@ -303,7 +303,7 @@ void RISCV::writePlt(uint8_t *buf, const Symbol &sym,
write32le(buf + 0, utype(AUIPC, X_X0, 0)); // lpad 0
write32le(buf + 0 + auipcOffset, utype(AUIPC, rd, hi20(offset)));
write32le(buf + 4 + auipcOffset,
- itype(ctx.arg.is64 ? LD : LW, rd, rd, lo12(offset)));
+ itype(ctx.arg.getIs64() ? LD : LW, rd, rd, lo12(offset)));
write32le(buf + 8 + auipcOffset, itype(JALR, X_T1, rd, 0));
if (!lpad)
write32le(buf + 12, itype(ADDI, X_X0, X_X0, 0));
@@ -438,11 +438,11 @@ void RISCV::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
// TLS symbol, so we cannot use handleTlsDesc (which sets NEEDS_TLSDESC).
// For TLSDESC->IE, use R_TPREL as well, but relocateAlloc uses isToLe
// (from HI20) to select the correct transform.
- sec.addReloc({ctx.arg.shared ? R_TLSDESC_PC : R_TPREL, type, offset,
+ sec.addReloc({ctx.arg.getShared() ? R_TLSDESC_PC : R_TPREL, type, offset,
addend, &sym});
continue;
case R_RISCV_TLSDESC_CALL:
- if (!ctx.arg.shared)
+ if (!ctx.arg.getShared())
sec.addReloc({R_TPREL, type, offset, addend, &sym});
continue;
@@ -452,7 +452,7 @@ void RISCV::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
continue;
case R_RISCV_TPREL_ADD:
case R_RISCV_RELAX:
- if (ctx.arg.relax)
+ if (ctx.arg.getRelax())
sec.addReloc({R_RELAX_HINT, type, offset, addend, &sym});
continue;
@@ -514,7 +514,7 @@ void RISCV::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
}
void RISCV::scanSection(InputSectionBase &sec, unsigned shard) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
elf::scanSection1<RISCV, ELF64LE>(*this, sec, shard);
else
elf::scanSection1<RISCV, ELF32LE>(*this, sec, shard);
@@ -722,7 +722,7 @@ void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
return;
case R_RISCV_TLSDESC:
// The addend is stored in the second word.
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write64le(loc + 8, val);
else
write32le(loc + 4, val);
@@ -747,7 +747,7 @@ static void tlsdescToIe(Ctx &ctx, uint8_t *loc, const Relocation &rel,
write32le(loc, utype(AUIPC, X_A0, hi20(val))); // auipc a0,<hi20>
break;
case R_RISCV_TLSDESC_CALL:
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write32le(loc, itype(LD, X_A0, X_A0, lo12(val))); // ld a0,<lo12>(a0)
else
write32le(loc, itype(LW, X_A0, X_A0, lo12(val))); // lw a0,<lo12>(a0)
@@ -947,7 +947,7 @@ static void relaxCall(Ctx &ctx, const InputSection &sec, size_t i, uint64_t loc,
sec.relaxAux->writes.push_back(0xa001); // c.j
remove = 6;
} else if (remove >= 6 && rvc && isInt<12>(displace) && rd == X_RA &&
- !ctx.arg.is64) { // RV32C only
+ !ctx.arg.getIs64()) { // RV32C only
sec.relaxAux->relocTypes[i] = R_RISCV_RVC_JUMP;
sec.relaxAux->writes.push_back(0x2001); // c.jal
remove = 6;
@@ -1269,8 +1269,8 @@ bool RISCV::synthesizeAlignAux(uint64_t &dot, InputSection *sec) {
// output relocation section is updated with all the newly synthesized ALIGN
// relocations.
bool RISCV::synthesizeAlign(uint64_t &dot, InputSection *sec) {
- assert(ctx.arg.relocatable);
- if (ctx.arg.is64)
+ assert(ctx.arg.getRelocatable());
+ if (ctx.arg.getIs64())
return synthesizeAlignAux<ELF64LE>(dot, sec);
return synthesizeAlignAux<ELF32LE>(dot, sec);
}
diff --git a/lld/ELF/Arch/SPARCV9.cpp b/lld/ELF/Arch/SPARCV9.cpp
index 7797990571def..27b36e5eb46b6 100644
--- a/lld/ELF/Arch/SPARCV9.cpp
+++ b/lld/ELF/Arch/SPARCV9.cpp
@@ -199,7 +199,7 @@ void SPARCV9::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
continue;
case R_SPARC_TLS_IE_LD:
case R_SPARC_TLS_IE_LDX:
- if (!ctx.arg.shared && !sym.isPreemptible)
+ if (!ctx.arg.getShared() && !sym.isPreemptible)
sec.addReloc({R_TPREL, type, offset, addend, &sym});
continue;
diff --git a/lld/ELF/Arch/SystemZ.cpp b/lld/ELF/Arch/SystemZ.cpp
index b76baf464a5e7..2fd1cd033c1fe 100644
--- a/lld/ELF/Arch/SystemZ.cpp
+++ b/lld/ELF/Arch/SystemZ.cpp
@@ -205,7 +205,7 @@ void SystemZ::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
// R_390_TLS_GDCALL/LDCALL (at the instruction start) for the same brasl.
// When optimizing TLS, skip PLT32DBL before maybeReportUndefined would
// flag __tls_get_offset as undefined.
- if (type == R_390_PLT32DBL && !ctx.arg.shared &&
+ if (type == R_390_PLT32DBL && !ctx.arg.getShared() &&
std::next(it) != rels.end()) {
RelType nextType = std::next(it)->getType(false);
if (nextType == R_390_TLS_GDCALL || nextType == R_390_TLS_LDCALL)
@@ -345,7 +345,7 @@ void SystemZ::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
// TLS DTPREL relocations:
case R_390_TLS_LDO32:
case R_390_TLS_LDO64:
- if (ctx.arg.shared)
+ if (ctx.arg.getShared())
sec.addReloc({R_DTPREL, type, offset, addend, &sym});
else
sec.addReloc({R_TPREL, type, offset, addend, &sym});
@@ -426,7 +426,7 @@ void SystemZ::relaxTlsGdCall(uint8_t *loc, const Relocation &rel) const {
RelExpr SystemZ::adjustGotPcExpr(RelType type, int64_t addend,
const uint8_t *loc) const {
// Only R_390_GOTENT with addend 2 can be relaxed.
- if (!ctx.arg.relax || addend != 2 || type != R_390_GOTENT)
+ if (!ctx.arg.getRelax() || addend != 2 || type != R_390_GOTENT)
return R_GOT_PC;
const uint16_t op = read16be(loc - 2);
diff --git a/lld/ELF/Arch/X86.cpp b/lld/ELF/Arch/X86.cpp
index 5b95ccdf50e46..0519d4b95e001 100644
--- a/lld/ELF/Arch/X86.cpp
+++ b/lld/ELF/Arch/X86.cpp
@@ -130,7 +130,7 @@ RelType X86::getDynRel(RelType type) const {
}
void X86::writePltHeader(uint8_t *buf) const {
- if (ctx.arg.isPic) {
+ if (ctx.arg.getIsPic()) {
const uint8_t v[] = {
0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx)
0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx)
@@ -154,7 +154,7 @@ void X86::writePltHeader(uint8_t *buf) const {
void X86::writePlt(uint8_t *buf, const Symbol &sym,
uint64_t pltEntryAddr) const {
unsigned relOff = ctx.in.relaPlt->entsize * sym.getPltIdx(ctx);
- if (ctx.arg.isPic) {
+ if (ctx.arg.getIsPic()) {
const uint8_t inst[] = {
0xff, 0xa3, 0, 0, 0, 0, // jmp *foo at GOT(%ebx)
0x68, 0, 0, 0, 0, // pushl $reloc_offset
@@ -269,8 +269,8 @@ void X86::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
++it;
continue;
case R_386_TLS_LDO_32:
- sec.addReloc(
- {ctx.arg.shared ? R_DTPREL : R_TPREL, type, offset, addend, &sym});
+ sec.addReloc({ctx.arg.getShared() ? R_DTPREL : R_TPREL, type, offset,
+ addend, &sym});
continue;
case R_386_TLS_GOTDESC:
ctx.in.gotPlt->hasGotPltOffRel.store(true, std::memory_order_relaxed);
@@ -279,7 +279,7 @@ void X86::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
case R_386_TLS_DESC_CALL:
// For executables, TLSDESC is optimized to IE or LE. Use R_TPREL as the
// rewrites for this relocation are identical.
- if (!ctx.arg.shared)
+ if (!ctx.arg.getShared())
sec.addReloc({R_TPREL, type, offset, addend, &sym});
continue;
@@ -607,7 +607,7 @@ void IntelIBT::writeGotPlt(uint8_t *buf, const Symbol &s) const {
void IntelIBT::writePlt(uint8_t *buf, const Symbol &sym,
uint64_t /*pltEntryAddr*/) const {
- if (ctx.arg.isPic) {
+ if (ctx.arg.getIsPic()) {
const uint8_t inst[] = {
0xf3, 0x0f, 0x1e, 0xfb, // endbr32
0xff, 0xa3, 0, 0, 0, 0, // jmp *name at GOT(%ebx)
@@ -780,8 +780,8 @@ void RetpolineNoPic::writePlt(uint8_t *buf, const Symbol &sym,
}
void elf::setX86TargetInfo(Ctx &ctx) {
- if (ctx.arg.zRetpolineplt) {
- if (ctx.arg.isPic)
+ if (ctx.arg.getZRetpolineplt()) {
+ if (ctx.arg.getIsPic())
ctx.target.reset(new RetpolinePic(ctx));
else
ctx.target.reset(new RetpolineNoPic(ctx));
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index c1d1db1d0133c..75be3bbf15f08 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -86,7 +86,7 @@ X86_64::X86_64(Ctx &ctx) : TargetInfo(ctx) {
pltRel = R_X86_64_JUMP_SLOT;
relativeRel = R_X86_64_RELATIVE;
iRelativeRel = R_X86_64_IRELATIVE;
- symbolicRel = ctx.arg.is64 ? R_X86_64_64 : R_X86_64_32;
+ symbolicRel = ctx.arg.getIs64() ? R_X86_64_64 : R_X86_64_32;
tlsDescRel = R_X86_64_TLSDESC;
tlsGotRel = R_X86_64_TPOFF64;
tlsModuleIndexRel = R_X86_64_DTPMOD64;
@@ -515,7 +515,7 @@ bool X86_64::relaxOnce(int pass) const {
// If the max VA is under 2^31, GOTPCRELX relocations cannot overflow. In
// -pie/-shared, the condition can be relaxed to test the max VA difference as
// there is no R_RELAX_GOT_PC_NOPIC.
- if (isUInt<31>(maxVA) || (isUInt<31>(maxVA - minVA) && ctx.arg.isPic))
+ if (isUInt<31>(maxVA) || (isUInt<31>(maxVA - minVA) && ctx.arg.getIsPic()))
return false;
SmallVector<InputSection *, 0> storage;
@@ -737,13 +737,13 @@ void X86_64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
continue;
case R_X86_64_DTPOFF32:
case R_X86_64_DTPOFF64:
- sec.addReloc(
- {ctx.arg.shared ? R_DTPREL : R_TPREL, type, offset, addend, &sym});
+ sec.addReloc({ctx.arg.getShared() ? R_DTPREL : R_TPREL, type, offset,
+ addend, &sym});
continue;
case R_X86_64_TLSDESC_CALL:
// For executables, TLSDESC is optimized to IE or LE. Use R_TPREL as the
// rewrites for this relocation are identical.
- if (!ctx.arg.shared)
+ if (!ctx.arg.getShared())
sec.addReloc({R_TPREL, type, offset, addend, &sym});
continue;
case R_X86_64_GOTPC32_TLSDESC:
@@ -766,13 +766,13 @@ void X86_64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels,
rs.process(expr, type, offset, sym, addend);
}
- if (ctx.arg.branchToBranch)
+ if (ctx.arg.getBranchToBranch())
llvm::stable_sort(sec.relocs(),
[](auto &l, auto &r) { return l.offset < r.offset; });
}
void X86_64::scanSection(InputSectionBase &sec, unsigned shard) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
elf::scanSection1<X86_64, ELF64LE>(*this, sec, shard);
else // ilp32
elf::scanSection1<X86_64, ELF32LE>(*this, sec, shard);
@@ -1320,7 +1320,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
// GOTPCRELX with addend != -4. Such an instruction does not load the full GOT
// entry, so we cannot relax the relocation. E.g. movl x at GOTPCREL+4(%rip),
// %rax (addend=0) loads the high 32 bits of the GOT entry.
- if (!ctx.arg.relax || addend != -4 ||
+ if (!ctx.arg.getRelax() || addend != -4 ||
(type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX &&
type != R_X86_64_CODE_4_GOTPCRELX))
return R_GOT_PC;
@@ -1344,7 +1344,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
// Relaxation of test, adc, add, and, cmp, or, sbb, sub, xor.
// If PIC then no relaxation is available.
- return ctx.arg.isPic ? R_GOT_PC : R_RELAX_GOT_PC_NOPIC;
+ return ctx.arg.getIsPic() ? R_GOT_PC : R_RELAX_GOT_PC_NOPIC;
}
// A subset of relaxations can only be applied for no-PIC. This method
@@ -1444,7 +1444,7 @@ static void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) {
if (op != 0xff) {
// We are relaxing a rip relative to an absolute, so compensate
// for the old -4 addend.
- assert(!rel.sym->file->ctx.arg.isPic);
+ assert(!rel.sym->file->ctx.arg.getIsPic());
relaxGotNoPic(loc, val + 4, op, modRm,
rel.type == R_X86_64_CODE_4_GOTPCRELX);
return;
@@ -1475,7 +1475,7 @@ static void relaxGot(uint8_t *loc, const Relocation &rel, uint64_t val) {
// B) Or a load of a stack pointer offset with an lea to r10 or r11.
bool X86_64::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
uint8_t stOther) const {
- if (!ctx.arg.is64) {
+ if (!ctx.arg.getIs64()) {
ErrAlways(ctx) << "target doesn't support split stacks";
return false;
}
@@ -1755,8 +1755,8 @@ void RetpolineZNow::writePlt(uint8_t *buf, const Symbol &sym,
}
void elf::setX86_64TargetInfo(Ctx &ctx) {
- if (ctx.arg.zRetpolineplt) {
- if (ctx.arg.zNow)
+ if (ctx.arg.getZRetpolineplt()) {
+ if (ctx.arg.getZNow())
ctx.target.reset(new RetpolineZNow(ctx));
else
ctx.target.reset(new Retpoline(ctx));
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index a43d5d509a80c..3cdd40b0b86c6 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/BinaryFormat/ELF.h"
@@ -189,17 +190,25 @@ struct VersionDefinition {
// Deferred file-load job: one per input, expanded by loadFiles().
struct LoadJob {
enum Kind : uint8_t { Obj, Bitcode, Archive, Shared, Binary };
+ LoadJob(llvm::MemoryBufferRef mbref, llvm::StringRef path, Kind kind,
+ bool inWholeArchive, bool lazy, bool asNeeded, bool withLOption,
+ uint32_t groupId);
llvm::MemoryBufferRef mbref;
llvm::StringRef path;
Kind kind;
- bool inWholeArchive;
- bool lazy;
- bool asNeeded;
- bool withLOption;
+ bool getInWholeArchive() const { return tarEntries.getFlag(0); }
+ void setInWholeArchive(bool Value) { tarEntries.setFlag(0, Value); }
+ bool getLazy() const { return tarEntries.getFlag(1); }
+ void setLazy(bool Value) { tarEntries.setFlag(1, Value); }
+ bool getAsNeeded() const { return tarEntries.getFlag(2); }
+ void setAsNeeded(bool Value) { tarEntries.setFlag(2, Value); }
+ bool getWithLOption() const { return tarEntries.getFlag(3); }
+ void setWithLOption(bool Value) { tarEntries.setFlag(3, Value); }
uint32_t groupId;
SmallVector<std::unique_ptr<InputFile>, 0> out;
std::vector<std::unique_ptr<llvm::MemoryBuffer>> thinBufs;
- SmallVector<std::pair<std::string, llvm::StringRef>, 0> tarEntries;
+ llvm::SmallVectorWithFlags<std::pair<std::string, llvm::StringRef>, 0, 4>
+ tarEntries;
};
class LinkerDriver {
@@ -300,23 +309,23 @@ struct Config {
llvm::StringRef thinLTOPrefixReplaceNew;
llvm::StringRef thinLTOPrefixReplaceNativeObject;
std::string rpath;
- llvm::SmallVector<VersionDefinition, 0> versionDefinitions;
+ llvm::SmallVectorWithFlags<VersionDefinition, 0, 4> versionDefinitions;
std::optional<llvm::DenseSet<llvm::StringRef>> retainSymbols;
- llvm::SmallVector<llvm::StringRef, 0> auxiliaryList;
- llvm::SmallVector<llvm::StringRef, 0> filterList;
- llvm::SmallVector<llvm::StringRef, 0> passPlugins;
- llvm::SmallVector<llvm::StringRef, 0> searchPaths;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> auxiliaryList;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> filterList;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> passPlugins;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> searchPaths;
llvm::SmallVector<llvm::StringRef, 0> symbolOrderingFile;
- llvm::SmallVector<llvm::StringRef, 0> thinLTOModulesToCompile;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> thinLTOModulesToCompile;
llvm::StringRef dtltoDistributor;
- llvm::SmallVector<llvm::StringRef, 0> dtltoDistributorArgs;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> dtltoDistributorArgs;
llvm::StringRef dtltoCompiler;
- llvm::SmallVector<llvm::StringRef, 0> dtltoCompilerPrependArgs;
- llvm::SmallVector<llvm::StringRef, 0> dtltoCompilerArgs;
- llvm::SmallVector<llvm::StringRef, 0> undefined;
- llvm::SmallVector<SymbolVersion, 0> dynamicList;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> dtltoCompilerPrependArgs;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> dtltoCompilerArgs;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> undefined;
+ llvm::SmallVectorWithFlags<SymbolVersion, 0, 4> dynamicList;
llvm::SmallVector<uint8_t, 0> buildIdVector;
- llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> mllvmOpts;
llvm::MapVector<std::pair<const InputSectionBase *, const InputSectionBase *>,
uint64_t>
callGraphProfile;
@@ -329,27 +338,65 @@ struct Config {
bool armHasBlx = false;
bool armHasMovtMovw = false;
bool armJ1J2BranchEncoding = false;
- bool armCMSESupport = false;
+ bool getArmCMSESupport() const { return remapInputsWildcards.getFlag(0); }
+ bool setArmCMSESupport(bool Value) {
+ remapInputsWildcards.setFlag(0, Value);
+ return Value;
+ }
bool asNeeded = false;
- bool armBe8 = false;
+ bool getArmBe8() const { return remapInputsWildcards.getFlag(1); }
+ void setArmBe8(bool Value) { remapInputsWildcards.setFlag(1, Value); }
BsymbolicKind bsymbolic = BsymbolicKind::None;
CGProfileSortKind callGraphProfileSort;
llvm::StringRef irpgoProfilePath;
- bool bpStartupFunctionSort = false;
- bool bpCompressionSortStartupFunctions = false;
- bool bpFunctionOrderForCompression = false;
- bool bpDataOrderForCompression = false;
- llvm::SmallVector<BPCompressionSortSpec> bpCompressionSortSpecs;
- bool bpVerboseSectionOrderer = false;
- bool branchToBranch = false;
- bool checkSections;
- bool checkDynamicRelocs;
+ bool getBpStartupFunctionSort() const {
+ return remapInputsWildcards.getFlag(2);
+ }
+ void setBpStartupFunctionSort(bool Value) {
+ remapInputsWildcards.setFlag(2, Value);
+ }
+ bool getBpCompressionSortStartupFunctions() const {
+ return remapInputsWildcards.getFlag(3);
+ }
+ void setBpCompressionSortStartupFunctions(bool Value) {
+ remapInputsWildcards.setFlag(3, Value);
+ }
+ bool getBpFunctionOrderForCompression() const {
+ return packageMetadata.getFlag(0);
+ }
+ void setBpFunctionOrderForCompression(bool Value) {
+ packageMetadata.setFlag(0, Value);
+ }
+ bool getBpDataOrderForCompression() const {
+ return packageMetadata.getFlag(1);
+ }
+ void setBpDataOrderForCompression(bool Value) {
+ packageMetadata.setFlag(1, Value);
+ }
+ llvm::SmallVectorWithFlags<BPCompressionSortSpec,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ BPCompressionSortSpec>::value,
+ 4>
+ bpCompressionSortSpecs;
+ bool getBpVerboseSectionOrderer() const { return packageMetadata.getFlag(2); }
+ void setBpVerboseSectionOrderer(bool Value) {
+ packageMetadata.setFlag(2, Value);
+ }
+ bool getBranchToBranch() const { return packageMetadata.getFlag(3); }
+ void setBranchToBranch(bool Value) { packageMetadata.setFlag(3, Value); }
+ bool getCheckSections() const { return warnBackrefsExclude.getFlag(0); }
+ void setCheckSections(bool Value) { warnBackrefsExclude.setFlag(0, Value); }
+ bool getCheckDynamicRelocs() const { return warnBackrefsExclude.getFlag(1); }
+ void setCheckDynamicRelocs(bool Value) {
+ warnBackrefsExclude.setFlag(1, Value);
+ }
std::optional<llvm::DebugCompressionType> compressDebugSections;
- llvm::SmallVector<
- std::tuple<llvm::GlobPattern, llvm::DebugCompressionType, unsigned>, 0>
+ llvm::SmallVectorWithFlags<
+ std::tuple<llvm::GlobPattern, llvm::DebugCompressionType, unsigned>, 0, 4>
compressSections;
- bool cref;
- llvm::SmallVector<std::pair<llvm::GlobPattern, uint64_t>, 0>
+ bool getCref() const { return warnBackrefsExclude.getFlag(2); }
+ void setCref(bool Value) { warnBackrefsExclude.setFlag(2, Value); }
+ llvm::SmallVectorWithFlags<std::pair<llvm::GlobPattern, uint64_t>, 0, 4>
deadRelocInNonAlloc;
bool debugNames;
bool demangle = true;
@@ -383,47 +430,97 @@ struct Config {
bool mmapOutputFile;
bool nmagic;
bool noinhibitExec;
- bool nostdlib;
- bool oFormatBinary;
- bool omagic;
- bool optEB = false;
- bool optEL = false;
- bool optimizeBBJumps;
- bool optRemarksWithHotness;
- bool picThunk;
- bool pie;
+ bool getNostdlib() const { return warnBackrefsExclude.getFlag(3); }
+ void setNostdlib(bool Value) { warnBackrefsExclude.setFlag(3, Value); }
+ bool getOFormatBinary() const { return shuffleSections.getFlag(0); }
+ void setOFormatBinary(bool Value) { shuffleSections.setFlag(0, Value); }
+ bool getOmagic() const { return shuffleSections.getFlag(1); }
+ void setOmagic(bool Value) { shuffleSections.setFlag(1, Value); }
+ bool getOptEB() const { return shuffleSections.getFlag(2); }
+ bool setOptEB(bool Value) {
+ shuffleSections.setFlag(2, Value);
+ return Value;
+ }
+ bool getOptEL() const { return shuffleSections.getFlag(3); }
+ bool setOptEL(bool Value) {
+ shuffleSections.setFlag(3, Value);
+ return Value;
+ }
+ bool getOptimizeBBJumps() const { return deadRelocInNonAlloc.getFlag(0); }
+ void setOptimizeBBJumps(bool Value) { deadRelocInNonAlloc.setFlag(0, Value); }
+ bool getOptRemarksWithHotness() const {
+ return deadRelocInNonAlloc.getFlag(1);
+ }
+ void setOptRemarksWithHotness(bool Value) {
+ deadRelocInNonAlloc.setFlag(1, Value);
+ }
+ bool getPicThunk() const { return deadRelocInNonAlloc.getFlag(2); }
+ void setPicThunk(bool Value) { deadRelocInNonAlloc.setFlag(2, Value); }
+ bool getPie() const { return deadRelocInNonAlloc.getFlag(3); }
+ void setPie(bool Value) { deadRelocInNonAlloc.setFlag(3, Value); }
llvm::StringRef printGcSections;
- bool printIcfSections;
- bool printMemoryUsage;
+ bool getPrintIcfSections() const { return compressSections.getFlag(0); }
+ void setPrintIcfSections(bool Value) { compressSections.setFlag(0, Value); }
+ bool getPrintMemoryUsage() const { return compressSections.getFlag(1); }
+ void setPrintMemoryUsage(bool Value) { compressSections.setFlag(1, Value); }
std::optional<uint64_t> randomizeSectionPadding;
- bool rejectMismatch;
- bool relax;
- bool relaxGP;
- bool relocatable;
- bool resolveGroups;
- bool relrGlibc = false;
+ bool getRejectMismatch() const { return compressSections.getFlag(2); }
+ void setRejectMismatch(bool Value) { compressSections.setFlag(2, Value); }
+ bool getRelax() const { return compressSections.getFlag(3); }
+ void setRelax(bool Value) { compressSections.setFlag(3, Value); }
+ bool getRelaxGP() const { return bpCompressionSortSpecs.getFlag(0); }
+ void setRelaxGP(bool Value) { bpCompressionSortSpecs.setFlag(0, Value); }
+ bool getRelocatable() const { return bpCompressionSortSpecs.getFlag(1); }
+ void setRelocatable(bool Value) { bpCompressionSortSpecs.setFlag(1, Value); }
+ bool getResolveGroups() const { return bpCompressionSortSpecs.getFlag(2); }
+ void setResolveGroups(bool Value) {
+ bpCompressionSortSpecs.setFlag(2, Value);
+ }
+ bool getRelrGlibc() const { return bpCompressionSortSpecs.getFlag(3); }
+ void setRelrGlibc(bool Value) { bpCompressionSortSpecs.setFlag(3, Value); }
bool relrPackDynRelocs = false;
llvm::DenseSet<llvm::StringRef> saveTempsArgs;
- llvm::SmallVector<std::pair<llvm::GlobPattern, uint32_t>, 0> shuffleSections;
- bool singleRoRx;
- bool singleXoRx;
- bool shared;
- bool symbolic;
+ llvm::SmallVectorWithFlags<std::pair<llvm::GlobPattern, uint32_t>, 0, 4>
+ shuffleSections;
+ bool getSingleRoRx() const { return mllvmOpts.getFlag(0); }
+ void setSingleRoRx(bool Value) { mllvmOpts.setFlag(0, Value); }
+ bool getSingleXoRx() const { return mllvmOpts.getFlag(1); }
+ void setSingleXoRx(bool Value) { mllvmOpts.setFlag(1, Value); }
+ bool getShared() const { return mllvmOpts.getFlag(2); }
+ void setShared(bool Value) { mllvmOpts.setFlag(2, Value); }
+ bool getSymbolic() const { return mllvmOpts.getFlag(3); }
+ void setSymbolic(bool Value) { mllvmOpts.setFlag(3, Value); }
bool isStatic = false;
- bool sysvHash = false;
- bool target1Rel;
- bool trace;
+ bool getSysvHash() const { return dynamicList.getFlag(0); }
+ bool setSysvHash(bool Value) {
+ dynamicList.setFlag(0, Value);
+ return Value;
+ }
+ bool getTarget1Rel() const { return dynamicList.getFlag(1); }
+ void setTarget1Rel(bool Value) { dynamicList.setFlag(1, Value); }
+ bool getTrace() const { return dynamicList.getFlag(2); }
+ void setTrace(bool Value) { dynamicList.setFlag(2, Value); }
bool thinLTOEmitImportsFiles;
bool thinLTOEmitIndexFiles;
- bool thinLTOIndexOnly;
- bool timeTraceEnabled;
- bool tocOptimize;
- bool pcRelOptimize;
- bool undefinedVersion;
- bool unique;
- bool useAndroidRelrTags = false;
- bool warnBackrefs;
- llvm::SmallVector<llvm::GlobPattern, 0> warnBackrefsExclude;
+ bool getThinLTOIndexOnly() const { return dynamicList.getFlag(3); }
+ void setThinLTOIndexOnly(bool Value) { dynamicList.setFlag(3, Value); }
+ bool getTimeTraceEnabled() const { return undefined.getFlag(0); }
+ void setTimeTraceEnabled(bool Value) { undefined.setFlag(0, Value); }
+ bool getTocOptimize() const { return undefined.getFlag(1); }
+ void setTocOptimize(bool Value) { undefined.setFlag(1, Value); }
+ bool getPcRelOptimize() const { return undefined.getFlag(2); }
+ void setPcRelOptimize(bool Value) { undefined.setFlag(2, Value); }
+ bool getUndefinedVersion() const { return undefined.getFlag(3); }
+ void setUndefinedVersion(bool Value) { undefined.setFlag(3, Value); }
+ bool getUnique() const { return dtltoCompilerArgs.getFlag(0); }
+ void setUnique(bool Value) { dtltoCompilerArgs.setFlag(0, Value); }
+ bool getUseAndroidRelrTags() const { return dtltoCompilerArgs.getFlag(1); }
+ void setUseAndroidRelrTags(bool Value) {
+ dtltoCompilerArgs.setFlag(1, Value);
+ }
+ bool getWarnBackrefs() const { return dtltoCompilerArgs.getFlag(2); }
+ void setWarnBackrefs(bool Value) { dtltoCompilerArgs.setFlag(2, Value); }
+ llvm::SmallVectorWithFlags<llvm::GlobPattern, 0, 4> warnBackrefsExclude;
bool warnCommon;
bool warnMissingEntry;
bool warnSymbolOrdering;
@@ -431,33 +528,78 @@ struct Config {
bool zCombreloc;
bool zCopyreloc;
bool zDynamicUndefined;
- bool zForceBti;
- bool zForceIbt;
- bool zGlobal;
- bool zHazardplt;
- bool zIfuncNoplt;
- bool zInitfirst;
- bool zInterpose;
- bool zKeepDataSectionPrefix;
- bool zKeepTextSectionPrefix;
- bool zLrodataAfterBss;
- bool zMarkPlt;
- bool zNoBtCfi;
- bool zNodefaultlib;
- bool zNodelete;
- bool zNodlopen;
- bool zNow;
- bool zOrigin;
- bool zPacPlt;
- bool zRelro;
- bool zRodynamic;
- bool zSectionHeader;
- bool zShstk;
- bool zStartStopGC;
+ bool getZForceBti() const { return dtltoCompilerArgs.getFlag(3); }
+ void setZForceBti(bool Value) { dtltoCompilerArgs.setFlag(3, Value); }
+ bool getZForceIbt() const { return dtltoCompilerPrependArgs.getFlag(0); }
+ void setZForceIbt(bool Value) { dtltoCompilerPrependArgs.setFlag(0, Value); }
+ bool getZGlobal() const { return dtltoCompilerPrependArgs.getFlag(1); }
+ void setZGlobal(bool Value) { dtltoCompilerPrependArgs.setFlag(1, Value); }
+ bool getZHazardplt() const { return dtltoCompilerPrependArgs.getFlag(2); }
+ void setZHazardplt(bool Value) { dtltoCompilerPrependArgs.setFlag(2, Value); }
+ bool getZIfuncNoplt() const { return dtltoCompilerPrependArgs.getFlag(3); }
+ void setZIfuncNoplt(bool Value) {
+ dtltoCompilerPrependArgs.setFlag(3, Value);
+ }
+ bool getZInitfirst() const { return dtltoDistributorArgs.getFlag(0); }
+ void setZInitfirst(bool Value) { dtltoDistributorArgs.setFlag(0, Value); }
+ bool getZInterpose() const { return dtltoDistributorArgs.getFlag(1); }
+ void setZInterpose(bool Value) { dtltoDistributorArgs.setFlag(1, Value); }
+ bool getZKeepDataSectionPrefix() const {
+ return dtltoDistributorArgs.getFlag(2);
+ }
+ void setZKeepDataSectionPrefix(bool Value) {
+ dtltoDistributorArgs.setFlag(2, Value);
+ }
+ bool getZKeepTextSectionPrefix() const {
+ return dtltoDistributorArgs.getFlag(3);
+ }
+ void setZKeepTextSectionPrefix(bool Value) {
+ dtltoDistributorArgs.setFlag(3, Value);
+ }
+ bool getZLrodataAfterBss() const {
+ return thinLTOModulesToCompile.getFlag(0);
+ }
+ void setZLrodataAfterBss(bool Value) {
+ thinLTOModulesToCompile.setFlag(0, Value);
+ }
+ bool getZMarkPlt() const { return thinLTOModulesToCompile.getFlag(1); }
+ void setZMarkPlt(bool Value) { thinLTOModulesToCompile.setFlag(1, Value); }
+ bool getZNoBtCfi() const { return thinLTOModulesToCompile.getFlag(2); }
+ void setZNoBtCfi(bool Value) { thinLTOModulesToCompile.setFlag(2, Value); }
+ bool getZNodefaultlib() const { return thinLTOModulesToCompile.getFlag(3); }
+ void setZNodefaultlib(bool Value) {
+ thinLTOModulesToCompile.setFlag(3, Value);
+ }
+ bool getZNodelete() const { return searchPaths.getFlag(0); }
+ void setZNodelete(bool Value) { searchPaths.setFlag(0, Value); }
+ bool getZNodlopen() const { return searchPaths.getFlag(1); }
+ void setZNodlopen(bool Value) { searchPaths.setFlag(1, Value); }
+ bool getZNow() const { return searchPaths.getFlag(2); }
+ void setZNow(bool Value) { searchPaths.setFlag(2, Value); }
+ bool getZOrigin() const { return searchPaths.getFlag(3); }
+ void setZOrigin(bool Value) { searchPaths.setFlag(3, Value); }
+ bool getZPacPlt() const { return passPlugins.getFlag(0); }
+ void setZPacPlt(bool Value) { passPlugins.setFlag(0, Value); }
+ bool getZRelro() const { return passPlugins.getFlag(1); }
+ bool setZRelro(bool Value) {
+ passPlugins.setFlag(1, Value);
+ return Value;
+ }
+ bool getZRodynamic() const { return passPlugins.getFlag(2); }
+ void setZRodynamic(bool Value) { passPlugins.setFlag(2, Value); }
+ bool getZSectionHeader() const { return passPlugins.getFlag(3); }
+ void setZSectionHeader(bool Value) { passPlugins.setFlag(3, Value); }
+ bool getZShstk() const { return filterList.getFlag(0); }
+ void setZShstk(bool Value) { filterList.setFlag(0, Value); }
+ bool getZStartStopGC() const { return filterList.getFlag(1); }
+ void setZStartStopGC(bool Value) { filterList.setFlag(1, Value); }
uint8_t zStartStopVisibility;
- bool zText;
- bool zRetpolineplt;
- bool zWxneeded;
+ bool getZText() const { return filterList.getFlag(2); }
+ void setZText(bool Value) { filterList.setFlag(2, Value); }
+ bool getZRetpolineplt() const { return filterList.getFlag(3); }
+ void setZRetpolineplt(bool Value) { filterList.setFlag(3, Value); }
+ bool getZWxneeded() const { return auxiliaryList.getFlag(0); }
+ void setZWxneeded(bool Value) { auxiliaryList.setFlag(0, Value); }
ZicfilpPolicy zZicfilp;
ZicfissPolicy zZicfiss;
DiscardPolicy discard;
@@ -470,7 +612,8 @@ struct Config {
UnresolvedPolicy unresolvedSymbolsInShlib;
Target2Policy target2;
GcsPolicy zGcs;
- bool power10Stubs;
+ bool getPower10Stubs() const { return auxiliaryList.getFlag(1); }
+ void setPower10Stubs(bool Value) { auxiliaryList.setFlag(1, Value); }
ARMVFPArgKind armVFPArgs = ARMVFPArgKind::Default;
BuildIdKind buildId = BuildIdKind::None;
SeparateSegmentKind zSeparate;
@@ -488,20 +631,23 @@ struct Config {
StringRef thinLTOJobs;
unsigned timeTraceGranularity;
int32_t splitStackAdjustSize;
- SmallVector<uint8_t, 0> packageMetadata;
+ llvm::SmallVectorWithFlags<uint8_t, 0, 4> packageMetadata;
// The following config options do not directly correspond to any
// particular command line options.
// True if we need to pass through relocations in input files to the
// output file. Usually false because we consume relocations.
- bool copyRelocs;
+ bool getCopyRelocs() const { return auxiliaryList.getFlag(2); }
+ void setCopyRelocs(bool Value) { auxiliaryList.setFlag(2, Value); }
// True if the target is ELF64. False if ELF32.
- bool is64;
+ bool getIs64() const { return auxiliaryList.getFlag(3); }
+ void setIs64(bool Value) { auxiliaryList.setFlag(3, Value); }
// True if the target is little-endian. False if big-endian.
- bool isLE;
+ bool getIsLE() const { return versionDefinitions.getFlag(0); }
+ void setIsLE(bool Value) { versionDefinitions.setFlag(0, Value); }
// endianness::little if isLE is true. endianness::big otherwise.
llvm::endianness endianness;
@@ -518,7 +664,8 @@ struct Config {
// name whatever that means. A fun hypothesis is that "EL" is short for
// little-endian written in the little-endian order, but I don't know
// if that's true.)
- bool isMips64EL;
+ bool getIsMips64EL() const { return versionDefinitions.getFlag(1); }
+ void setIsMips64EL(bool Value) { versionDefinitions.setFlag(1, Value); }
// Holds set of ELF header flags for the target.
uint32_t eflags = 0;
@@ -537,10 +684,12 @@ struct Config {
// Each ABI defines its relocation type. IsRela is true if target
// uses RELA. As far as we know, all 64-bit ABIs are using RELA. A
// few 32-bit ABIs are using RELA too.
- bool isRela;
+ bool getIsRela() const { return versionDefinitions.getFlag(2); }
+ void setIsRela(bool Value) { versionDefinitions.setFlag(2, Value); }
// True if we are creating position-independent code.
- bool isPic;
+ bool getIsPic() const { return versionDefinitions.getFlag(3); }
+ void setIsPic(bool Value) { versionDefinitions.setFlag(3, Value); }
// 4 for ELF32, 8 for ELF64.
int wordsize;
@@ -566,7 +715,8 @@ struct Config {
// If an input file equals a key, remap it to the value.
llvm::DenseMap<llvm::StringRef, llvm::StringRef> remapInputs;
// If an input file matches a wildcard pattern, remap it to the value.
- llvm::SmallVector<std::pair<llvm::GlobPattern, llvm::StringRef>, 0>
+ llvm::SmallVectorWithFlags<std::pair<llvm::GlobPattern, llvm::StringRef>, 0,
+ 4>
remapInputsWildcards;
};
@@ -592,8 +742,12 @@ struct UndefinedDiag {
InputSectionBase *sec;
uint64_t offset;
};
- SmallVector<Loc, 0> locs;
- bool isWarning;
+ llvm::SmallVectorWithFlags<Loc, 0> locs;
+ bool getIsWarning() const { return locs.getFlag(0); }
+ void setIsWarning(bool Value) { locs.setFlag(0, Value); }
+
+ UndefinedDiag(Undefined *sym, SmallVector<Loc, 0> locs, bool isWarning)
+ : sym(sym), locs(unsigned(isWarning), std::move(locs)) {}
};
// Linker generated sections which can be used as inputs.
@@ -738,9 +892,11 @@ struct Ctx : CommonLinkerContext {
SmallVector<UndefinedDiag, 0> undefErrs;
// Symbols in a non-prevailing COMDAT group which should be changed to an
// Undefined.
- SmallVector<std::pair<Symbol *, unsigned>, 0> nonPrevailingSyms;
+ llvm::SmallVectorWithFlags<std::pair<Symbol *, unsigned>, 0>
+ nonPrevailingSyms;
// A tuple of (reference, extractedFile, sym). Used by --why-extract=.
- SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0>
+ llvm::SmallVectorWithFlags<
+ std::tuple<std::string, const InputFile *, const Symbol &>, 0, 4>
whyExtractRecords;
// A mapping from a symbol to an InputFile referencing it backward. Used by
// --warn-backrefs.
@@ -756,14 +912,20 @@ struct Ctx : CommonLinkerContext {
// Dummy Undefined for relocations without a symbol.
Undefined *dummySym = nullptr;
// True if symbols can be exported (isExported) or preemptible.
- bool hasDynsym = false;
+ bool getHasDynsym() const { return whyExtractRecords.getFlag(0); }
+ void setHasDynsym(bool Value) { whyExtractRecords.setFlag(0, Value); }
// True if there are TLS IE relocations. Set DF_STATIC_TLS if -shared.
std::atomic<bool> hasTlsIe{false};
// True if we need to reserve two .got entries for local-dynamic TLS model.
std::atomic<bool> needsTlsLd{false};
// True if all native vtable symbols have corresponding type info symbols
// during LTO.
- bool ltoAllVtablesHaveTypeInfos = false;
+ bool getLtoAllVtablesHaveTypeInfos() const {
+ return whyExtractRecords.getFlag(1);
+ }
+ void setLtoAllVtablesHaveTypeInfos(bool Value) {
+ whyExtractRecords.setFlag(1, Value);
+ }
// Number of Vernaux entries (needed shared object names).
uint32_t vernauxNum = 0;
@@ -790,12 +952,15 @@ struct Ctx : CommonLinkerContext {
// True if performing the embedded unoptimized dynamic debugging relocatable
// link.
- bool inDynDbgLink = false;
+ bool getInDynDbgLink() const { return whyExtractRecords.getFlag(2); }
+ void setInDynDbgLink(bool Value) { whyExtractRecords.setFlag(2, Value); }
// True if performing dynamic debugging style relocatable link rather than a
// regular relocatable link.
- bool dynDbgRelocatable = false;
+ bool getDynDbgRelocatable() const { return whyExtractRecords.getFlag(3); }
+ void setDynDbgRelocatable(bool Value) { whyExtractRecords.setFlag(3, Value); }
// True if the link contains dynamic debugging.
- bool hasDynDbg = false;
+ bool getHasDynDbg() const { return nonPrevailingSyms.getFlag(0); }
+ void setHasDynDbg(bool Value) { nonPrevailingSyms.setFlag(0, Value); }
// Pointer to the output of the embedded unoptimized dynamic debugging
// relocatable link.
std::unique_ptr<llvm::FileOutputBuffer> dynDbgOutput;
diff --git a/lld/ELF/DWARF.cpp b/lld/ELF/DWARF.cpp
index 78fd013bef22c..a458d9c701055 100644
--- a/lld/ELF/DWARF.cpp
+++ b/lld/ELF/DWARF.cpp
@@ -110,7 +110,7 @@ LLDDwarfObj<ELFT>::findAux(const InputSectionBase &sec, uint64_t pos,
const ObjFile<ELFT> *file = sec.getFile<ELFT>();
Ctx &ctx = sec.getCtx();
- uint32_t symIndex = rel.getSymbol(ctx.arg.isMips64EL);
+ uint32_t symIndex = rel.getSymbol(ctx.arg.getIsMips64EL());
const typename ELFT::Sym &sym = file->template getELFSyms<ELFT>()[symIndex];
uint32_t secIndex = file->getSectionIndex(sym);
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 134aae9ef98ad..68473ed991e8a 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -236,17 +236,11 @@ void LinkerDriver::addFile(StringRef path, bool withLOption) {
MemoryBufferRef mbref = *buffer;
if (ctx.arg.formatBinary) {
- loadJobs.push_back({mbref,
- path,
- LoadJob::Binary,
+ loadJobs.push_back({mbref, path, LoadJob::Binary,
/*inWholeArchive=*/false,
/*lazy=*/false,
/*asNeeded=*/false,
- /*withLOption=*/false,
- nextGroupId,
- {},
- {},
- {}});
+ /*withLOption=*/false, nextGroupId});
} else {
auto magic = identify_magic(mbref.getBuffer());
if (magic == file_magic::unknown) {
@@ -275,17 +269,8 @@ void LinkerDriver::addFile(StringRef path, bool withLOption) {
Err(ctx) << path << ": unknown file type";
return;
}
- loadJobs.push_back({mbref,
- path,
- kind,
- inWholeArchive,
- inLib,
- ctx.arg.asNeeded,
- withLOption,
- nextGroupId,
- {},
- {},
- {}});
+ loadJobs.push_back({mbref, path, kind, inWholeArchive, inLib,
+ ctx.arg.asNeeded, withLOption, nextGroupId});
}
if (!isInGroup)
++nextGroupId;
@@ -334,7 +319,7 @@ static void checkOptions(Ctx &ctx) {
if (!ctx.arg.cmseOutputLib.empty())
ErrAlways(ctx) << "--out-implib may not be used without --cmse-implib";
}
- if (ctx.arg.fixCortexA8 && !ctx.arg.isLE)
+ if (ctx.arg.fixCortexA8 && !ctx.arg.getIsLE())
ErrAlways(ctx)
<< "--fix-cortex-a8 is not supported on big endian targets";
} else {
@@ -346,7 +331,7 @@ static void checkOptions(Ctx &ctx) {
ErrAlways(ctx) << "--out-implib is only supported on ARM targets";
if (ctx.arg.fixCortexA8)
ErrAlways(ctx) << "--fix-cortex-a8 is only supported on ARM targets";
- if (ctx.arg.armBe8)
+ if (ctx.arg.getArmBe8())
ErrAlways(ctx) << "--be8 is only supported on ARM targets";
}
@@ -355,9 +340,9 @@ static void checkOptions(Ctx &ctx) {
ErrAlways(ctx) << "--execute-only is only supported on AArch64 targets";
if (ctx.arg.fixCortexA53Errata843419)
ErrAlways(ctx) << "--fix-cortex-a53-843419 is only supported on AArch64";
- if (ctx.arg.zPacPlt)
+ if (ctx.arg.getZPacPlt())
ErrAlways(ctx) << "-z pac-plt only supported on AArch64";
- if (ctx.arg.zForceBti)
+ if (ctx.arg.getZForceBti())
ErrAlways(ctx) << "-z force-bti only supported on AArch64";
if (ctx.arg.zBtiReport != ReportPolicy::None)
ErrAlways(ctx) << "-z bti-report only supported on AArch64";
@@ -377,15 +362,15 @@ static void checkOptions(Ctx &ctx) {
<< "-z execute-only-report only supported on AArch64 and ARM";
if (ctx.arg.emachine != EM_PPC64) {
- if (ctx.arg.tocOptimize)
+ if (ctx.arg.getTocOptimize())
ErrAlways(ctx) << "--toc-optimize is only supported on PowerPC64 targets";
- if (ctx.arg.pcRelOptimize)
+ if (ctx.arg.getPcRelOptimize())
ErrAlways(ctx)
<< "--pcrel-optimize is only supported on PowerPC64 targets";
}
if (ctx.arg.emachine != EM_RISCV) {
- if (ctx.arg.relaxGP)
+ if (ctx.arg.getRelaxGP())
ErrAlways(ctx) << "--relax-gp is only supported on RISC-V targets";
if (ctx.arg.zZicfilpUnlabeledReport != ReportPolicy::None)
ErrAlways(ctx) << "-z zicfilip-unlabeled-report is only supported on "
@@ -405,56 +390,56 @@ static void checkOptions(Ctx &ctx) {
ctx.arg.zCetReport != ReportPolicy::None)
ErrAlways(ctx) << "-z cet-report only supported on X86 and X86_64";
- if (ctx.arg.zMarkPlt) {
+ if (ctx.arg.getZMarkPlt()) {
if (ctx.arg.emachine != EM_X86_64)
ErrAlways(ctx) << "-z mark-plt only supported on X86_64";
// The PLT entry address is stored in the JUMP_SLOT relocation's addend, so
// -z mark-plt requires RELA relocations. REL relocations have no addend
// field and the .got.plt entry is already occupied by the lazy-binding
// address, so the information would be silently lost.
- else if (!ctx.arg.isRela)
+ else if (!ctx.arg.getIsRela())
ErrAlways(ctx) << "-z mark-plt requires -z rela";
}
- if (ctx.arg.pie && ctx.arg.shared)
+ if (ctx.arg.getPie() && ctx.arg.getShared())
ErrAlways(ctx) << "-shared and -pie may not be used together";
- if (!ctx.arg.shared && !ctx.arg.filterList.empty())
+ if (!ctx.arg.getShared() && !ctx.arg.filterList.empty())
ErrAlways(ctx) << "-F may not be used without -shared";
- if (!ctx.arg.shared && !ctx.arg.auxiliaryList.empty())
+ if (!ctx.arg.getShared() && !ctx.arg.auxiliaryList.empty())
ErrAlways(ctx) << "-f may not be used without -shared";
if (ctx.arg.strip == StripPolicy::All && ctx.arg.emitRelocs)
ErrAlways(ctx) << "--strip-all and --emit-relocs may not be used together";
- if (ctx.arg.zText && ctx.arg.zIfuncNoplt)
+ if (ctx.arg.getZText() && ctx.arg.getZIfuncNoplt())
ErrAlways(ctx) << "-z text and -z ifunc-noplt may not be used together";
- if (ctx.arg.relocatable) {
- if (ctx.arg.shared)
+ if (ctx.arg.getRelocatable()) {
+ if (ctx.arg.getShared())
ErrAlways(ctx) << "-r and -shared may not be used together";
if (ctx.arg.gdbIndex)
ErrAlways(ctx) << "-r and --gdb-index may not be used together";
if (ctx.arg.icf != ICFLevel::None)
ErrAlways(ctx) << "-r and --icf may not be used together";
- if (ctx.arg.pie)
+ if (ctx.arg.getPie())
ErrAlways(ctx) << "-r and -pie may not be used together";
if (ctx.arg.exportDynamic)
ErrAlways(ctx) << "-r and --export-dynamic may not be used together";
if (ctx.arg.debugNames)
ErrAlways(ctx) << "-r and --debug-names may not be used together";
- if (!ctx.arg.zSectionHeader)
+ if (!ctx.arg.getZSectionHeader())
ErrAlways(ctx) << "-r and -z nosectionheader may not be used together";
}
if (ctx.arg.executeOnly) {
- if (ctx.arg.singleRoRx && !ctx.script->hasSectionsCommand)
+ if (ctx.arg.getSingleRoRx() && !ctx.script->getHasSectionsCommand())
ErrAlways(ctx)
<< "--execute-only and --no-rosegment cannot be used together";
}
- if (ctx.arg.zRetpolineplt && ctx.arg.zForceIbt)
+ if (ctx.arg.getZRetpolineplt() && ctx.arg.getZForceIbt())
ErrAlways(ctx) << "-z force-ibt may not be used with -z retpolineplt";
}
@@ -640,6 +625,14 @@ constexpr const char *saveTempsValues[] = {
"resolution", "preopt", "promote", "internalize", "import",
"opt", "precodegen", "prelink", "combinedindex"};
+LoadJob::LoadJob(MemoryBufferRef mbref, StringRef path, Kind kind,
+ bool inWholeArchive, bool lazy, bool asNeeded,
+ bool withLOption, uint32_t groupId)
+ : mbref(mbref), path(path), kind(kind), groupId(groupId),
+ tarEntries(decltype(this->tarEntries)::withFlags(
+ unsigned(inWholeArchive) | (unsigned(lazy) << 1) |
+ (unsigned(asNeeded) << 2) | (unsigned(withLOption) << 3))) {}
+
LinkerDriver::LinkerDriver(Ctx &ctx) : ctx(ctx) {}
void LinkerDriver::waitForLTOCleanup() {
@@ -682,7 +675,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (args.hasArg(OPT_v) || args.hasArg(OPT_version))
Msg(ctx) << getLLDVersion() << " (compatible with GNU linkers)";
- if (const char *path = getReproduceOption(args); !ctx.inDynDbgLink && path) {
+ if (const char *path = getReproduceOption(args);
+ !ctx.getInDynDbgLink() && path) {
// Note that --reproduce is a debug option so you can ignore it
// if you are trying to understand the whole picture of the code.
Expected<std::unique_ptr<TarWriter>> errOrWriter =
@@ -711,7 +705,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
return;
// Initialize time trace profiler.
- if (ctx.arg.timeTraceEnabled)
+ if (ctx.arg.getTimeTraceEnabled())
timeTraceProfilerInitialize(ctx.arg.timeTraceGranularity, ctx.arg.progName);
{
@@ -734,7 +728,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// writing the time trace data.
waitForLTOCleanup();
- if (ctx.arg.timeTraceEnabled) {
+ if (ctx.arg.getTimeTraceEnabled()) {
checkError(ctx.e, timeTraceProfilerWrite(
args.getLastArgValue(OPT_time_trace_eq).str(),
ctx.arg.outputFile));
@@ -756,7 +750,7 @@ static void setUnresolvedSymbolPolicy(Ctx &ctx, opt::InputArgList &args) {
: UnresolvedPolicy::Warn;
// -shared implies --unresolved-symbols=ignore-all because missing
// symbols are likely to be resolved at runtime.
- bool diagRegular = !ctx.arg.shared, diagShlib = !ctx.arg.shared;
+ bool diagRegular = !ctx.arg.getShared(), diagShlib = !ctx.arg.getShared();
for (const opt::Arg *arg : args) {
switch (arg->getOption().getID()) {
@@ -890,13 +884,13 @@ static void parsePackageMetadata(Ctx &ctx, const opt::Arg &arg) {
return;
}
}
- ctx.arg.packageMetadata = std::move(decoded);
+ ctx.arg.packageMetadata.assign(std::move(decoded));
}
static StripPolicy getStrip(Ctx &ctx, opt::InputArgList &args) {
if (args.hasArg(OPT_relocatable))
return StripPolicy::None;
- if (!ctx.arg.zSectionHeader)
+ if (!ctx.arg.getZSectionHeader())
return StripPolicy::All;
auto *arg = args.getLastArg(OPT_strip_all, OPT_strip_debug);
@@ -1071,14 +1065,14 @@ processCallGraphRelocations(Ctx &ctx, SmallVector<uint32_t, 32> &symbolIndices,
ArrayRef<typename ELFT::Rela> relas =
CHECK(obj.relas(sec), "could not retrieve cg profile rela section");
for (const typename ELFT::Rela &rel : relas)
- symbolIndices.push_back(rel.getSymbol(ctx.arg.isMips64EL));
+ symbolIndices.push_back(rel.getSymbol(ctx.arg.getIsMips64EL()));
break;
}
if (sec.sh_type == SHT_REL) {
ArrayRef<typename ELFT::Rel> rels =
CHECK(obj.rels(sec), "could not retrieve cg profile rel section");
for (const typename ELFT::Rel &rel : rels)
- symbolIndices.push_back(rel.getSymbol(ctx.arg.isMips64EL));
+ symbolIndices.push_back(rel.getSymbol(ctx.arg.getIsMips64EL()));
break;
}
}
@@ -1170,7 +1164,7 @@ static void ltoValidateAllVtablesHaveTypeInfos(Ctx &ctx,
[&](StringRef s) { return pat->match(s); });
}
- ctx.ltoAllVtablesHaveTypeInfos = vtableSymbolsWithNoRTTI.empty();
+ ctx.setLtoAllVtablesHaveTypeInfos(vtableSymbolsWithNoRTTI.empty());
// Check for unmatched RTTI symbols
for (StringRef s : vtableSymbolsWithNoRTTI) {
Msg(ctx) << "--lto-validate-all-vtables-have-type-infos: RTTI missing for "
@@ -1244,12 +1238,12 @@ static void parseBPOrdererOptions(Ctx &ctx, opt::InputArgList &args) {
if (auto *arg = args.getLastArg(OPT_bp_compression_sort)) {
StringRef s = arg->getValue();
if (s == "function") {
- ctx.arg.bpFunctionOrderForCompression = true;
+ ctx.arg.setBpFunctionOrderForCompression(true);
} else if (s == "data") {
- ctx.arg.bpDataOrderForCompression = true;
+ ctx.arg.setBpDataOrderForCompression(true);
} else if (s == "both") {
- ctx.arg.bpFunctionOrderForCompression = true;
- ctx.arg.bpDataOrderForCompression = true;
+ ctx.arg.setBpFunctionOrderForCompression(true);
+ ctx.arg.setBpDataOrderForCompression(true);
} else if (s != "none") {
ErrAlways(ctx) << arg->getSpelling()
<< ": expected [none|function|data|both]";
@@ -1261,7 +1255,7 @@ static void parseBPOrdererOptions(Ctx &ctx, opt::InputArgList &args) {
if (auto *arg = args.getLastArg(OPT_bp_startup_sort)) {
StringRef s = arg->getValue();
if (s == "function") {
- ctx.arg.bpStartupFunctionSort = true;
+ ctx.arg.setBpStartupFunctionSort(true);
} else if (s != "none") {
ErrAlways(ctx) << arg->getSpelling() << ": expected [none|function]";
}
@@ -1270,17 +1264,18 @@ static void parseBPOrdererOptions(Ctx &ctx, opt::InputArgList &args) {
"--call-graph-ordering-file";
}
- ctx.arg.bpCompressionSortStartupFunctions =
+ ctx.arg.setBpCompressionSortStartupFunctions(
args.hasFlag(OPT_bp_compression_sort_startup_functions,
- OPT_no_bp_compression_sort_startup_functions, false);
- ctx.arg.bpVerboseSectionOrderer = args.hasArg(OPT_verbose_bp_section_orderer);
+ OPT_no_bp_compression_sort_startup_functions, false));
+ ctx.arg.setBpVerboseSectionOrderer(
+ args.hasArg(OPT_verbose_bp_section_orderer));
ctx.arg.irpgoProfilePath = args.getLastArgValue(OPT_irpgo_profile);
if (ctx.arg.irpgoProfilePath.empty()) {
- if (ctx.arg.bpStartupFunctionSort)
+ if (ctx.arg.getBpStartupFunctionSort())
ErrAlways(ctx) << "--bp-startup-sort=function must be used with "
"--irpgo-profile";
- if (ctx.arg.bpCompressionSortStartupFunctions)
+ if (ctx.arg.getBpCompressionSortStartupFunctions())
ErrAlways(ctx)
<< "--bp-compression-sort-startup-functions must be used with "
"--irpgo-profile";
@@ -1410,8 +1405,8 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ctx.arg.fatLTOObjects =
args.hasFlag(OPT_fat_lto_objects, OPT_no_fat_lto_objects, false);
ctx.arg.memtagMode = getMemtagMode(ctx, args);
- ctx.arg.auxiliaryList = args::getStrings(args, OPT_auxiliary);
- ctx.arg.armBe8 = args.hasArg(OPT_be8);
+ ctx.arg.auxiliaryList.assign(args::getStrings(args, OPT_auxiliary));
+ ctx.arg.setArmBe8(args.hasArg(OPT_be8));
if (opt::Arg *arg = args.getLastArg(
OPT_Bno_symbolic, OPT_Bsymbolic_non_weak_functions,
OPT_Bsymbolic_functions, OPT_Bsymbolic_non_weak, OPT_Bsymbolic)) {
@@ -1426,16 +1421,16 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
}
ctx.arg.callGraphProfileSort = getCGProfileSortKind(ctx, args);
parseBPOrdererOptions(ctx, args);
- ctx.arg.checkSections =
- args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
+ ctx.arg.setCheckSections(
+ args.hasFlag(OPT_check_sections, OPT_no_check_sections, true));
ctx.arg.chroot = args.getLastArgValue(OPT_chroot);
if (auto *arg = args.getLastArg(OPT_compress_debug_sections)) {
ctx.arg.compressDebugSections =
getCompressionType(ctx, arg->getValue(), "--compress-debug-sections");
}
- ctx.arg.cref = args.hasArg(OPT_cref);
- ctx.arg.optimizeBBJumps =
- args.hasFlag(OPT_optimize_bb_jumps, OPT_no_optimize_bb_jumps, false);
+ ctx.arg.setCref(args.hasArg(OPT_cref));
+ ctx.arg.setOptimizeBBJumps(
+ args.hasFlag(OPT_optimize_bb_jumps, OPT_no_optimize_bb_jumps, false));
ctx.arg.debugNames = args.hasFlag(OPT_debug_names, OPT_no_debug_names, false);
ctx.arg.demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
ctx.arg.dependencyFile = args.getLastArgValue(OPT_dependency_file);
@@ -1444,13 +1439,13 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ctx.arg.disableVerify = args.hasArg(OPT_disable_verify);
ctx.arg.discard = getDiscard(args);
ctx.arg.dtltoDistributor = args.getLastArgValue(OPT_thinlto_distributor_eq);
- ctx.arg.dtltoDistributorArgs =
- args::getStrings(args, OPT_thinlto_distributor_arg);
+ ctx.arg.dtltoDistributorArgs.assign(
+ args::getStrings(args, OPT_thinlto_distributor_arg));
ctx.arg.dtltoCompiler = args.getLastArgValue(OPT_thinlto_remote_compiler_eq);
- ctx.arg.dtltoCompilerPrependArgs =
- args::getStrings(args, OPT_thinlto_remote_compiler_prepend_arg);
- ctx.arg.dtltoCompilerArgs =
- args::getStrings(args, OPT_thinlto_remote_compiler_arg);
+ ctx.arg.dtltoCompilerPrependArgs.assign(
+ args::getStrings(args, OPT_thinlto_remote_compiler_prepend_arg));
+ ctx.arg.dtltoCompilerArgs.assign(
+ args::getStrings(args, OPT_thinlto_remote_compiler_arg));
ctx.arg.dwoDir = args.getLastArgValue(OPT_plugin_opt_dwo_dir_eq);
ctx.arg.dynamicLinker = getDynamicLinker(ctx, args);
ctx.arg.ehFrameHdr =
@@ -1470,7 +1465,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ctx.arg.exportDynamic =
args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false) ||
args.hasArg(OPT_shared);
- ctx.arg.filterList = args::getStrings(args, OPT_filter);
+ ctx.arg.filterList.assign(args::getStrings(args, OPT_filter));
ctx.arg.fini = args.getLastArgValue(OPT_fini, "_fini");
ctx.arg.fixCortexA53Errata843419 =
args.hasArg(OPT_fix_cortex_a53_843419) && !args.hasArg(OPT_relocatable);
@@ -1529,9 +1524,9 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ctx.arg.mmapOutputFile =
args.hasFlag(OPT_mmap_output_file, OPT_no_mmap_output_file, false);
ctx.arg.nmagic = args.hasFlag(OPT_nmagic, OPT_no_nmagic, false);
- ctx.arg.nostdlib = args.hasArg(OPT_nostdlib);
- ctx.arg.oFormatBinary = isOutputFormatBinary(ctx, args);
- ctx.arg.omagic = args.hasFlag(OPT_omagic, OPT_no_omagic, false);
+ ctx.arg.setNostdlib(args.hasArg(OPT_nostdlib));
+ ctx.arg.setOFormatBinary(isOutputFormatBinary(ctx, args));
+ ctx.arg.setOmagic(args.hasFlag(OPT_omagic, OPT_no_omagic, false));
ctx.arg.optRemarksFilename = args.getLastArgValue(OPT_opt_remarks_filename);
ctx.arg.optStatsFilename = args.getLastArgValue(OPT_plugin_opt_stats_file);
@@ -1547,16 +1542,16 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
}
ctx.arg.optRemarksPasses = args.getLastArgValue(OPT_opt_remarks_passes);
- ctx.arg.optRemarksWithHotness = args.hasArg(OPT_opt_remarks_with_hotness);
+ ctx.arg.setOptRemarksWithHotness(args.hasArg(OPT_opt_remarks_with_hotness));
ctx.arg.optRemarksFormat = args.getLastArgValue(OPT_opt_remarks_format);
ctx.arg.optimize = args::getInteger(args, OPT_O, 1);
ctx.arg.orphanHandling = getOrphanHandling(ctx, args);
ctx.arg.outputFile = args.getLastArgValue(OPT_o);
if (auto *arg = args.getLastArg(OPT_package_metadata))
parsePackageMetadata(ctx, *arg);
- ctx.arg.pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
- ctx.arg.printIcfSections =
- args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
+ ctx.arg.setPie(args.hasFlag(OPT_pie, OPT_no_pie, false));
+ ctx.arg.setPrintIcfSections(
+ args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false));
if (auto *arg =
args.getLastArg(OPT_print_gc_sections, OPT_no_print_gc_sections,
OPT_print_gc_sections_eq)) {
@@ -1565,16 +1560,16 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
else if (arg->getOption().matches(OPT_print_gc_sections_eq))
ctx.arg.printGcSections = arg->getValue();
}
- ctx.arg.printMemoryUsage = args.hasArg(OPT_print_memory_usage);
+ ctx.arg.setPrintMemoryUsage(args.hasArg(OPT_print_memory_usage));
ctx.arg.printArchiveStats = args.getLastArgValue(OPT_print_archive_stats);
ctx.arg.printSymbolOrder = args.getLastArgValue(OPT_print_symbol_order);
- ctx.arg.rejectMismatch = !args.hasArg(OPT_no_warn_mismatch);
- ctx.arg.relax = args.hasFlag(OPT_relax, OPT_no_relax, true);
- ctx.arg.relaxGP = args.hasFlag(OPT_relax_gp, OPT_no_relax_gp, false);
+ ctx.arg.setRejectMismatch(!args.hasArg(OPT_no_warn_mismatch));
+ ctx.arg.setRelax(args.hasFlag(OPT_relax, OPT_no_relax, true));
+ ctx.arg.setRelaxGP(args.hasFlag(OPT_relax_gp, OPT_no_relax_gp, false));
ctx.arg.rpath = getRpath(args);
- ctx.arg.relocatable = args.hasArg(OPT_relocatable);
- ctx.arg.resolveGroups =
- !args.hasArg(OPT_relocatable) || args.hasArg(OPT_force_group_allocation);
+ ctx.arg.setRelocatable(args.hasArg(OPT_relocatable));
+ ctx.arg.setResolveGroups(!args.hasArg(OPT_relocatable) ||
+ args.hasArg(OPT_force_group_allocation));
if (args.hasArg(OPT_save_temps)) {
// --save-temps implies saving all temps.
@@ -1589,23 +1584,23 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
}
}
- ctx.arg.searchPaths = args::getStrings(args, OPT_library_path);
+ ctx.arg.searchPaths.assign(args::getStrings(args, OPT_library_path));
ctx.arg.sectionStartMap = getSectionStartMap(ctx, args);
- ctx.arg.shared = args.hasArg(OPT_shared);
+ ctx.arg.setShared(args.hasArg(OPT_shared));
if (args.hasArg(OPT_randomize_section_padding))
ctx.arg.randomizeSectionPadding =
args::getInteger(args, OPT_randomize_section_padding, 0);
- ctx.arg.singleRoRx = !args.hasFlag(OPT_rosegment, OPT_no_rosegment, true);
- ctx.arg.singleXoRx = !args.hasFlag(OPT_xosegment, OPT_no_xosegment, false);
+ ctx.arg.setSingleRoRx(!args.hasFlag(OPT_rosegment, OPT_no_rosegment, true));
+ ctx.arg.setSingleXoRx(!args.hasFlag(OPT_xosegment, OPT_no_xosegment, false));
ctx.arg.soName = args.getLastArgValue(OPT_soname);
ctx.arg.sortSection = getSortSection(ctx, args);
ctx.arg.splitStackAdjustSize =
args::getInteger(args, OPT_split_stack_adjust_size, 16384);
- ctx.arg.zSectionHeader =
- getZFlag(args, "sectionheader", "nosectionheader", true);
+ ctx.arg.setZSectionHeader(
+ getZFlag(args, "sectionheader", "nosectionheader", true));
ctx.arg.strip = getStrip(ctx, args); // needs zSectionHeader
ctx.arg.sysroot = args.getLastArgValue(OPT_sysroot);
- ctx.arg.target1Rel = args.hasFlag(OPT_target1_rel, OPT_target1_abs, false);
+ ctx.arg.setTarget1Rel(args.hasFlag(OPT_target1_rel, OPT_target1_abs, false));
ctx.arg.target2 = getTarget2(ctx, args);
ctx.arg.thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
ctx.arg.thinLTOCachePolicy = CHECK(
@@ -1615,15 +1610,15 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ctx.arg.thinLTOEmitIndexFiles = args.hasArg(OPT_thinlto_emit_index_files) ||
args.hasArg(OPT_thinlto_index_only) ||
args.hasArg(OPT_thinlto_index_only_eq);
- ctx.arg.thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) ||
- args.hasArg(OPT_thinlto_index_only_eq);
+ ctx.arg.setThinLTOIndexOnly(args.hasArg(OPT_thinlto_index_only) ||
+ args.hasArg(OPT_thinlto_index_only_eq));
ctx.arg.thinLTOIndexOnlyArg = args.getLastArgValue(OPT_thinlto_index_only_eq);
ctx.arg.thinLTOObjectSuffixReplace =
getOldNewOptions(ctx, args, OPT_thinlto_object_suffix_replace_eq);
std::tie(ctx.arg.thinLTOPrefixReplaceOld, ctx.arg.thinLTOPrefixReplaceNew,
ctx.arg.thinLTOPrefixReplaceNativeObject) =
getOldNewOptionsExtra(ctx, args, OPT_thinlto_prefix_replace_eq);
- if (ctx.arg.thinLTOEmitIndexFiles && !ctx.arg.thinLTOIndexOnly) {
+ if (ctx.arg.thinLTOEmitIndexFiles && !ctx.arg.getThinLTOIndexOnly()) {
if (args.hasArg(OPT_thinlto_object_suffix_replace_eq))
ErrAlways(ctx) << "--thinlto-object-suffix-replace is not supported with "
"--thinlto-emit-index-files";
@@ -1637,21 +1632,21 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
<< "--thinlto-prefix-replace=old_dir;new_dir;obj_dir must be used with "
"--thinlto-index-only=";
}
- ctx.arg.thinLTOModulesToCompile =
- args::getStrings(args, OPT_thinlto_single_module_eq);
- ctx.arg.timeTraceEnabled =
- args.hasArg(OPT_time_trace_eq) && !ctx.e.disableOutput;
+ ctx.arg.thinLTOModulesToCompile.assign(
+ args::getStrings(args, OPT_thinlto_single_module_eq));
+ ctx.arg.setTimeTraceEnabled(args.hasArg(OPT_time_trace_eq) &&
+ !ctx.e.disableOutput);
ctx.arg.timeTraceGranularity =
args::getInteger(args, OPT_time_trace_granularity, 500);
- ctx.arg.trace = args.hasArg(OPT_trace);
- ctx.arg.undefined = args::getStrings(args, OPT_undefined);
- ctx.arg.undefinedVersion =
- args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, false);
- ctx.arg.unique = args.hasArg(OPT_unique);
- ctx.arg.useAndroidRelrTags = args.hasFlag(
- OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false);
- ctx.arg.warnBackrefs =
- args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false);
+ ctx.arg.setTrace(args.hasArg(OPT_trace));
+ ctx.arg.undefined.assign(args::getStrings(args, OPT_undefined));
+ ctx.arg.setUndefinedVersion(
+ args.hasFlag(OPT_undefined_version, OPT_no_undefined_version, false));
+ ctx.arg.setUnique(args.hasArg(OPT_unique));
+ ctx.arg.setUseAndroidRelrTags(args.hasFlag(
+ OPT_use_android_relr_tags, OPT_no_use_android_relr_tags, false));
+ ctx.arg.setWarnBackrefs(
+ args.hasFlag(OPT_warn_backrefs, OPT_no_warn_backrefs, false));
ctx.arg.warnCommon = args.hasFlag(OPT_warn_common, OPT_no_warn_common, false);
ctx.arg.warnSymbolOrdering =
args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true);
@@ -1667,52 +1662,52 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
}
ctx.arg.zCombreloc = getZFlag(args, "combreloc", "nocombreloc", true);
ctx.arg.zCopyreloc = getZFlag(args, "copyreloc", "nocopyreloc", true);
- ctx.arg.zForceBti = hasZOption(args, "force-bti");
- ctx.arg.zForceIbt = hasZOption(args, "force-ibt");
+ ctx.arg.setZForceBti(hasZOption(args, "force-bti"));
+ ctx.arg.setZForceIbt(hasZOption(args, "force-ibt"));
ctx.arg.zZicfilp = getZZicfilp(ctx, args);
ctx.arg.zZicfiss = getZZicfiss(ctx, args);
ctx.arg.zGcs = getZGcs(ctx, args);
- ctx.arg.zGlobal = hasZOption(args, "global");
+ ctx.arg.setZGlobal(hasZOption(args, "global"));
ctx.arg.zGnustack = getZGnuStack(args);
- ctx.arg.zHazardplt = hasZOption(args, "hazardplt");
- ctx.arg.zIfuncNoplt = hasZOption(args, "ifunc-noplt");
- ctx.arg.zInitfirst = hasZOption(args, "initfirst");
- ctx.arg.zInterpose = hasZOption(args, "interpose");
- ctx.arg.zKeepDataSectionPrefix = getZFlag(
- args, "keep-data-section-prefix", "nokeep-data-section-prefix", false);
- ctx.arg.zKeepTextSectionPrefix = getZFlag(
- args, "keep-text-section-prefix", "nokeep-text-section-prefix", false);
- ctx.arg.zLrodataAfterBss =
- getZFlag(args, "lrodata-after-bss", "nolrodata-after-bss", false);
- ctx.arg.zMarkPlt = getZFlag(args, "mark-plt", "nomark-plt", false);
- ctx.arg.zNoBtCfi = hasZOption(args, "nobtcfi");
- ctx.arg.zNodefaultlib = hasZOption(args, "nodefaultlib");
- ctx.arg.zNodelete = hasZOption(args, "nodelete");
- ctx.arg.zNodlopen = hasZOption(args, "nodlopen");
- ctx.arg.zNow = getZFlag(args, "now", "lazy", false);
- ctx.arg.zOrigin = hasZOption(args, "origin");
- ctx.arg.zPacPlt = getZFlag(args, "pac-plt", "nopac-plt", false);
- ctx.arg.zRelro = getZFlag(args, "relro", "norelro", true);
- ctx.arg.zRetpolineplt = hasZOption(args, "retpolineplt");
- ctx.arg.zRodynamic = hasZOption(args, "rodynamic");
+ ctx.arg.setZHazardplt(hasZOption(args, "hazardplt"));
+ ctx.arg.setZIfuncNoplt(hasZOption(args, "ifunc-noplt"));
+ ctx.arg.setZInitfirst(hasZOption(args, "initfirst"));
+ ctx.arg.setZInterpose(hasZOption(args, "interpose"));
+ ctx.arg.setZKeepDataSectionPrefix(getZFlag(
+ args, "keep-data-section-prefix", "nokeep-data-section-prefix", false));
+ ctx.arg.setZKeepTextSectionPrefix(getZFlag(
+ args, "keep-text-section-prefix", "nokeep-text-section-prefix", false));
+ ctx.arg.setZLrodataAfterBss(
+ getZFlag(args, "lrodata-after-bss", "nolrodata-after-bss", false));
+ ctx.arg.setZMarkPlt(getZFlag(args, "mark-plt", "nomark-plt", false));
+ ctx.arg.setZNoBtCfi(hasZOption(args, "nobtcfi"));
+ ctx.arg.setZNodefaultlib(hasZOption(args, "nodefaultlib"));
+ ctx.arg.setZNodelete(hasZOption(args, "nodelete"));
+ ctx.arg.setZNodlopen(hasZOption(args, "nodlopen"));
+ ctx.arg.setZNow(getZFlag(args, "now", "lazy", false));
+ ctx.arg.setZOrigin(hasZOption(args, "origin"));
+ ctx.arg.setZPacPlt(getZFlag(args, "pac-plt", "nopac-plt", false));
+ ctx.arg.setZRelro(getZFlag(args, "relro", "norelro", true));
+ ctx.arg.setZRetpolineplt(hasZOption(args, "retpolineplt"));
+ ctx.arg.setZRodynamic(hasZOption(args, "rodynamic"));
ctx.arg.zSeparate = getZSeparate(args);
- ctx.arg.zShstk = hasZOption(args, "shstk");
+ ctx.arg.setZShstk(hasZOption(args, "shstk"));
ctx.arg.zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0);
- ctx.arg.zStartStopGC =
- getZFlag(args, "start-stop-gc", "nostart-stop-gc", true);
+ ctx.arg.setZStartStopGC(
+ getZFlag(args, "start-stop-gc", "nostart-stop-gc", true));
ctx.arg.zStartStopVisibility = getZStartStopVisibility(ctx, args);
- ctx.arg.zText = getZFlag(args, "text", "notext", true);
- ctx.arg.zWxneeded = hasZOption(args, "wxneeded");
+ ctx.arg.setZText(getZFlag(args, "text", "notext", true));
+ ctx.arg.setZWxneeded(hasZOption(args, "wxneeded"));
setUnresolvedSymbolPolicy(ctx, args);
- ctx.arg.power10Stubs = args.getLastArgValue(OPT_power10_stubs_eq) != "no";
- ctx.arg.branchToBranch = args.hasFlag(
- OPT_branch_to_branch, OPT_no_branch_to_branch, ctx.arg.optimize >= 2);
+ ctx.arg.setPower10Stubs(args.getLastArgValue(OPT_power10_stubs_eq) != "no");
+ ctx.arg.setBranchToBranch(args.hasFlag(
+ OPT_branch_to_branch, OPT_no_branch_to_branch, ctx.arg.optimize >= 2));
if (opt::Arg *arg = args.getLastArg(OPT_eb, OPT_el)) {
if (arg->getOption().matches(OPT_eb))
- ctx.arg.optEB = true;
+ ctx.arg.setOptEB(true);
else
- ctx.arg.optEL = true;
+ ctx.arg.setOptEL(true);
}
for (opt::Arg *arg : args.filtered(OPT_remap_inputs)) {
@@ -1749,7 +1744,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ErrAlways(ctx) << errPrefix << pat.takeError() << ": " << kv.first;
}
- if (ctx.arg.zForceBti) {
+ if (ctx.arg.getZForceBti()) {
ctx.arg.zBtiReport = ReportPolicy::Warning;
ctx.arg.zBtiReportSource = "-z force-bti";
}
@@ -1873,7 +1868,7 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
<< arg->getValue() << "'";
}
- ctx.arg.passPlugins = args::getStrings(args, OPT_load_pass_plugins);
+ ctx.arg.passPlugins.assign(args::getStrings(args, OPT_load_pass_plugins));
// Parse -mllvm options.
for (const auto *arg : args.filtered(OPT_mllvm)) {
@@ -1947,11 +1942,11 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
if (auto *arg = args.getLastArg(OPT_hash_style)) {
StringRef s = arg->getValue();
if (s == "sysv")
- ctx.arg.sysvHash = true;
+ ctx.arg.setSysvHash(true);
else if (s == "gnu")
ctx.arg.gnuHash = true;
else if (s == "both")
- ctx.arg.sysvHash = ctx.arg.gnuHash = true;
+ ctx.arg.setSysvHash(ctx.arg.gnuHash = true);
else
ErrAlways(ctx) << "unknown --hash-style: " << s;
}
@@ -1962,13 +1957,13 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
// Page alignment can be disabled by the -n (--nmagic) and -N (--omagic).
// As PT_GNU_RELRO relies on Paging, do not create it when we have disabled
// it. Also disable RELRO for -r.
- if (ctx.arg.nmagic || ctx.arg.omagic || ctx.arg.relocatable)
- ctx.arg.zRelro = false;
+ if (ctx.arg.nmagic || ctx.arg.getOmagic() || ctx.arg.getRelocatable())
+ ctx.arg.setZRelro(false);
std::tie(ctx.arg.buildId, ctx.arg.buildIdVector) = getBuildId(ctx, args);
if (getZFlag(args, "pack-relative-relocs", "nopack-relative-relocs", false)) {
- ctx.arg.relrGlibc = true;
+ ctx.arg.setRelrGlibc(true);
ctx.arg.relrPackDynRelocs = true;
} else {
std::tie(ctx.arg.androidPackDynRelocs, ctx.arg.relrPackDynRelocs) =
@@ -2019,8 +2014,8 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
// --export-dynamic-symbol-list specifies a list of --export-dynamic-symbol
// patterns. --dynamic-list is --export-dynamic-symbol-list plus -Bsymbolic
// like semantics.
- ctx.arg.symbolic =
- ctx.arg.bsymbolic == BsymbolicKind::All || args.hasArg(OPT_dynamic_list);
+ ctx.arg.setSymbolic(ctx.arg.bsymbolic == BsymbolicKind::All ||
+ args.hasArg(OPT_dynamic_list));
for (auto *arg :
args.filtered(OPT_dynamic_list, OPT_export_dynamic_symbol_list))
if (std::optional<MemoryBufferRef> buffer = readFile(ctx, arg->getValue()))
@@ -2043,14 +2038,14 @@ static void setConfigs(Ctx &ctx, opt::InputArgList &args) {
ELFKind k = ctx.arg.ekind;
uint16_t m = ctx.arg.emachine;
- ctx.arg.copyRelocs = (ctx.arg.relocatable || ctx.arg.emitRelocs);
- ctx.arg.is64 = (k == ELF64LEKind || k == ELF64BEKind);
- ctx.arg.isLE = (k == ELF32LEKind || k == ELF64LEKind);
- ctx.arg.endianness = ctx.arg.isLE ? endianness::little : endianness::big;
- ctx.arg.isMips64EL = (k == ELF64LEKind && m == EM_MIPS);
- ctx.arg.isPic = ctx.arg.pie || ctx.arg.shared;
- ctx.arg.picThunk = args.hasArg(OPT_pic_veneer, ctx.arg.isPic);
- ctx.arg.wordsize = ctx.arg.is64 ? 8 : 4;
+ ctx.arg.setCopyRelocs((ctx.arg.getRelocatable() || ctx.arg.emitRelocs));
+ ctx.arg.setIs64((k == ELF64LEKind || k == ELF64BEKind));
+ ctx.arg.setIsLE((k == ELF32LEKind || k == ELF64LEKind));
+ ctx.arg.endianness = ctx.arg.getIsLE() ? endianness::little : endianness::big;
+ ctx.arg.setIsMips64EL((k == ELF64LEKind && m == EM_MIPS));
+ ctx.arg.setIsPic(ctx.arg.getPie() || ctx.arg.getShared());
+ ctx.arg.setPicThunk(args.hasArg(OPT_pic_veneer, ctx.arg.getIsPic()));
+ ctx.arg.wordsize = ctx.arg.getIs64() ? 8 : 4;
// ELF defines two different ways to store relocation addends as shown below:
//
@@ -2066,7 +2061,7 @@ static void setConfigs(Ctx &ctx, opt::InputArgList &args) {
// We pick the format for dynamic relocations according to the psABI for each
// processor, but a contrary choice can be made if the dynamic loader
// supports.
- ctx.arg.isRela = getIsRela(ctx, args);
+ ctx.arg.setIsRela(getIsRela(ctx, args));
// If the output uses REL relocations we must store the dynamic relocation
// addends to the output sections. We also store addends for RELA relocations
@@ -2075,7 +2070,7 @@ static void setConfigs(Ctx &ctx, opt::InputArgList &args) {
// any standard conforming tool can find it in r_addend.
ctx.arg.writeAddends = args.hasFlag(OPT_apply_dynamic_relocs,
OPT_no_apply_dynamic_relocs, false) ||
- !ctx.arg.isRela;
+ !ctx.arg.getIsRela();
// Validation of dynamic relocation addends is on by default for assertions
// builds and disabled otherwise. This check is enabled when writeAddends is
// true.
@@ -2084,26 +2079,27 @@ static void setConfigs(Ctx &ctx, opt::InputArgList &args) {
#else
bool checkDynamicRelocsDefault = false;
#endif
- ctx.arg.checkDynamicRelocs =
- args.hasFlag(OPT_check_dynamic_relocations,
- OPT_no_check_dynamic_relocations, checkDynamicRelocsDefault);
- ctx.arg.tocOptimize =
- args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, m == EM_PPC64);
- ctx.arg.pcRelOptimize =
- args.hasFlag(OPT_pcrel_optimize, OPT_no_pcrel_optimize, m == EM_PPC64);
+ ctx.arg.setCheckDynamicRelocs(args.hasFlag(OPT_check_dynamic_relocations,
+ OPT_no_check_dynamic_relocations,
+ checkDynamicRelocsDefault));
+ ctx.arg.setTocOptimize(
+ args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, m == EM_PPC64));
+ ctx.arg.setPcRelOptimize(
+ args.hasFlag(OPT_pcrel_optimize, OPT_no_pcrel_optimize, m == EM_PPC64));
if (!args.hasArg(OPT_hash_style)) {
if (ctx.arg.emachine == EM_MIPS)
- ctx.arg.sysvHash = true;
+ ctx.arg.setSysvHash(true);
else
- ctx.arg.sysvHash = ctx.arg.gnuHash = true;
+ ctx.arg.setSysvHash(ctx.arg.gnuHash = true);
}
// Set default entry point and output file if not specified by command line or
// linker scripts.
ctx.arg.warnMissingEntry =
- (!ctx.arg.entry.empty() || (!ctx.arg.shared && !ctx.arg.relocatable));
- if (ctx.arg.entry.empty() && !ctx.arg.relocatable)
+ (!ctx.arg.entry.empty() ||
+ (!ctx.arg.getShared() && !ctx.arg.getRelocatable()));
+ if (ctx.arg.entry.empty() && !ctx.arg.getRelocatable())
ctx.arg.entry = ctx.arg.emachine == EM_MIPS ? "__start" : "_start";
if (ctx.arg.outputFile.empty())
ctx.arg.outputFile = "a.out";
@@ -2159,7 +2155,7 @@ void LinkerDriver::loadFiles() {
job.kind == LoadJob::Bitcode
? file_magic::bitcode
: file_magic::elf_relocatable,
- "", 0, job.lazy));
+ "", 0, job.getLazy()));
break;
case LoadJob::Archive: {
// Scan all archive members rather than using the archive symbol
@@ -2169,11 +2165,11 @@ void LinkerDriver::loadFiles() {
// --warn-backrefs.
auto members = getArchiveMembers(ctx, job);
job.out.reserve(members.size());
- bool lazy = !job.inWholeArchive;
+ bool lazy = !job.getInWholeArchive();
for (const auto &[mb, offset] : members) {
auto mm = identify_magic(mb.getBuffer());
if (mm == file_magic::elf_relocatable || mm == file_magic::bitcode ||
- job.inWholeArchive)
+ job.getInWholeArchive())
job.out.push_back(makeFile(mb, mm, job.path, offset, lazy));
else
Warn(ctx) << job.path << ": archive member '"
@@ -2189,9 +2185,9 @@ void LinkerDriver::loadFiles() {
StringRef bufPath = job.mbref.getBufferIdentifier();
auto f = std::make_unique<SharedFile>(
ctx, job.mbref,
- job.withLOption ? path::filename(bufPath) : bufPath);
+ job.getWithLOption() ? path::filename(bufPath) : bufPath);
f->init();
- f->isNeeded = !job.asNeeded;
+ f->isNeeded = !job.getAsNeeded();
job.out.push_back(std::move(f));
break;
}
@@ -2229,7 +2225,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
std::vector<std::tuple<bool, bool, bool>> stack;
// -r implies -Bstatic and has precedence over -Bdynamic.
- ctx.arg.isStatic = ctx.arg.relocatable;
+ ctx.arg.isStatic = ctx.arg.getRelocatable();
// Iterate over argv to process input files and positional arguments.
std::optional<MemoryBufferRef> defaultScript;
@@ -2281,7 +2277,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
ctx.arg.isStatic = true;
break;
case OPT_Bdynamic:
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
ctx.arg.isStatic = false;
break;
case OPT_whole_archive:
@@ -2293,7 +2289,7 @@ void LinkerDriver::createFiles(opt::InputArgList &args) {
case OPT_just_symbols:
if (std::optional<MemoryBufferRef> mb = readFile(ctx, arg->getValue())) {
files.push_back(createObjFile(ctx, *mb));
- files.back()->justSymbols = true;
+ files.back()->setJustSymbols(true);
}
break;
case OPT_in_implib:
@@ -2384,7 +2380,7 @@ static uint64_t getMaxPageSize(Ctx &ctx, opt::InputArgList &args) {
ErrAlways(ctx) << "max-page-size: value isn't a power of 2";
return ctx.target->defaultMaxPageSize;
}
- if (ctx.arg.nmagic || ctx.arg.omagic) {
+ if (ctx.arg.nmagic || ctx.arg.getOmagic()) {
if (val != ctx.target->defaultMaxPageSize)
Warn(ctx)
<< "-z max-page-size set, but paging disabled by omagic or nmagic";
@@ -2402,7 +2398,7 @@ static uint64_t getCommonPageSize(Ctx &ctx, opt::InputArgList &args) {
ErrAlways(ctx) << "common-page-size: value isn't a power of 2";
return ctx.target->defaultCommonPageSize;
}
- if (ctx.arg.nmagic || ctx.arg.omagic) {
+ if (ctx.arg.nmagic || ctx.arg.getOmagic()) {
if (val != ctx.target->defaultCommonPageSize)
Warn(ctx)
<< "-z common-page-size set, but paging disabled by omagic or nmagic";
@@ -2833,7 +2829,7 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
// For defined symbols in non-relocatable output,
// compute isExported and parse '@'.
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
for (Symbol *sym : obj->getGlobalSymbols()) {
if (!sym->isDefined())
continue;
@@ -3109,9 +3105,10 @@ static void readSecurityNotes(Ctx &ctx) {
"GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED";
}
- if (ctx.arg.zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
+ if (ctx.arg.getZForceBti() &&
+ !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
- } else if (ctx.arg.zForceIbt &&
+ } else if (ctx.arg.getZForceIbt() &&
!(features & GNU_PROPERTY_X86_FEATURE_1_IBT)) {
if (ctx.arg.zCetReport == ReportPolicy::None)
Warn(ctx) << f
@@ -3119,8 +3116,9 @@ static void readSecurityNotes(Ctx &ctx) {
"GNU_PROPERTY_X86_FEATURE_1_IBT property";
features |= GNU_PROPERTY_X86_FEATURE_1_IBT;
}
- if (ctx.arg.zPacPlt && !(hasValidPauthAbiCoreInfo ||
- (features & GNU_PROPERTY_AARCH64_FEATURE_1_PAC))) {
+ if (ctx.arg.getZPacPlt() &&
+ !(hasValidPauthAbiCoreInfo ||
+ (features & GNU_PROPERTY_AARCH64_FEATURE_1_PAC))) {
Warn(ctx) << f
<< ": -z pac-plt: file does not have "
"GNU_PROPERTY_AARCH64_FEATURE_1_PAC property and no valid "
@@ -3160,7 +3158,7 @@ static void readSecurityNotes(Ctx &ctx) {
}
// Force enable Shadow Stack.
- if (ctx.arg.zShstk)
+ if (ctx.arg.getZShstk())
ctx.arg.andFeatures |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
// Force enable/disable GCS
@@ -3255,8 +3253,8 @@ static void linkDynamicDebug(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {
dctx.e.initialize(ctx.e.outs(), ctx.e.errs(), ctx.e.exitEarly,
ctx.e.disableOutput);
initContext(dctx, script, ctx.arg.progName);
- dctx.inDynDbgLink = true;
- dctx.dynDbgRelocatable = !ctx.arg.relocatable;
+ dctx.setInDynDbgLink(true);
+ dctx.setDynDbgRelocatable(!ctx.arg.getRelocatable());
for (auto *file : ctx.objectFiles) {
auto *obj = cast<ObjFile<ELFT>>(file);
@@ -3274,7 +3272,7 @@ static void linkDynamicDebug(Ctx &ctx, ArrayRef<WrappedSymbol> wrapped) {
std::vector<const char *> args{
dctx.arg.progName.data(), "-r", "-o", "-",
saveArg(Twine("-O") + Twine(ctx.arg.optimize))};
- if (ctx.arg.resolveGroups)
+ if (ctx.arg.getResolveGroups())
args.push_back("--force-group-allocation");
for (const auto &ws : wrapped)
args.push_back(saveArg(Twine("--wrap=") + ws.sym->getName()));
@@ -3308,22 +3306,22 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// ICF is incompatible with dynamic debugging: the inner ELF references outer
// symbols that folding would merge away.
- if (ctx.hasDynDbg && ctx.arg.icf != ICFLevel::None) {
+ if (ctx.getHasDynDbg() && ctx.arg.icf != ICFLevel::None) {
Warn(ctx) << "ICF disabled because it is incompatible with dynamic "
"debugging";
ctx.arg.icf = ICFLevel::None;
}
// Create dynamic sections for dynamic linking and static PIE.
- ctx.hasDynsym = !ctx.sharedFiles.empty() || ctx.arg.isPic;
- ctx.arg.exportDynamic &= ctx.hasDynsym;
+ ctx.setHasDynsym(!ctx.sharedFiles.empty() || ctx.arg.getIsPic());
+ ctx.arg.exportDynamic &= ctx.getHasDynsym();
// Preemptibility of undefined symbols when ctx.hasDynsym is true. Default is
// true for dynamic linking.
ctx.arg.zDynamicUndefined =
getZFlag(args, "dynamic-undefined-weak", "nodynamic-undefined-weak",
- ctx.sharedFiles.size() || ctx.arg.shared) &&
- ctx.hasDynsym;
+ ctx.sharedFiles.size() || ctx.arg.getShared()) &&
+ ctx.getHasDynsym();
// If an entry symbol is in a static archive, pull out that file now.
if (Symbol *sym = ctx.symtab->find(ctx.arg.entry))
@@ -3417,7 +3415,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
ctx.out.elfHeader = std::make_unique<OutputSection>(ctx, "", 0, SHF_ALLOC);
// We need to create some reserved symbols such as _end. Create them.
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
addReservedSymbols(ctx);
// Apply version scripts.
@@ -3425,7 +3423,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// For a relocatable output, version scripts don't make sense, and
// parsing a symbol version string (e.g. dropping "@ver1" from a symbol
// name "foo at ver1") rather do harm, so we don't call this if -r is given.
- if (!ctx.arg.relocatable) {
+ if (!ctx.arg.getRelocatable()) {
llvm::TimeTraceScope timeScope("Process symbol versions");
ctx.symtab->scanVersionScript();
@@ -3439,8 +3437,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// --plugin-opt=emit-asm create output files in bitcode or assembly code,
// respectively. When only certain thinLTO modules are specified for
// compilation, the intermediate object file are the expected output.
- const bool skipLinkedOutput = ctx.arg.thinLTOIndexOnly || ctx.arg.emitLLVM ||
- ctx.arg.ltoEmitAsm ||
+ const bool skipLinkedOutput = ctx.arg.getThinLTOIndexOnly() ||
+ ctx.arg.emitLLVM || ctx.arg.ltoEmitAsm ||
!ctx.arg.thinLTOModulesToCompile.empty();
// Handle --lto-validate-all-vtables-have-type-infos.
@@ -3574,7 +3572,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
ctx.arg.imageBase = getImageBase(ctx, args);
// This adds a .comment section containing a version string.
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
ctx.inputSections.push_back(createCommentSection(ctx));
// Split SHF_MERGE and .eh_frame sections into pieces in preparation for garbage collection.
@@ -3588,7 +3586,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
createTaggedSymbols(ctx);
}
- if (ctx.hasDynDbg) {
+ if (ctx.getHasDynDbg()) {
llvm::TimeTraceScope timeScope("Link dynamic debugging");
linkDynamicDebug<ELFT>(ctx, wrapped);
if (errCount(ctx))
@@ -3602,7 +3600,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// Some input sections that are used for exception handling need to be moved
// into synthetic sections. Do that now so that they aren't assigned to
// output sections in the usual way.
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
combineEhSections(ctx);
// Merge .hexagon.attributes sections.
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 62c42bdbb550d..038004650b89b 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -243,7 +243,8 @@ bool ICF<ELFT>::constantEq(const InputSection *secA, Relocs<RelTy> ra,
auto rai = ra.begin(), rae = ra.end(), rbi = rb.begin();
for (; rai != rae; ++rai, ++rbi) {
if (rai->r_offset != rbi->r_offset ||
- rai->getType(ctx.arg.isMips64EL) != rbi->getType(ctx.arg.isMips64EL))
+ rai->getType(ctx.arg.getIsMips64EL()) !=
+ rbi->getType(ctx.arg.getIsMips64EL()))
return false;
uint64_t addA = getAddend<ELFT>(*rai);
@@ -540,7 +541,8 @@ template <class ELFT> void ICF<ELFT>::run() {
Log(ctx) << "ICF needed " << cnt << " iterations";
auto print = [&ctx = ctx]() -> ELFSyncStream {
- return {ctx, ctx.arg.printIcfSections ? DiagLevel::Msg : DiagLevel::None};
+ return {ctx,
+ ctx.arg.getPrintIcfSections() ? DiagLevel::Msg : DiagLevel::None};
};
// Merge sections by the equivalence class.
forEachClassRange(0, sections.size(), [&](size_t begin, size_t end) {
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index a1f921a875605..def63076a8a42 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -193,7 +193,7 @@ static void updateSupportedARMFeatures(Ctx &ctx,
return;
if (arch >= ARMBuildAttrs::CPUArch::v8_M_Base &&
profile == ARMBuildAttrs::MicroControllerProfile)
- ctx.arg.armCMSESupport = true;
+ ctx.arg.setArmCMSESupport(true);
// The thumb PLT entries require Thumb2 which can be used on multiple archs.
// For now, let's limit it to ones where ARM isn't available and we know have
@@ -300,7 +300,7 @@ template <class ELFT> static void doParseFile(Ctx &ctx, InputFile *file) {
return;
// Lazy object file
- if (file->lazy) {
+ if (file->getLazy()) {
if (auto *f = dyn_cast<BitcodeFile>(file)) {
ctx.lazyBitcodeFiles.push_back(f);
f->parseLazy();
@@ -310,7 +310,7 @@ template <class ELFT> static void doParseFile(Ctx &ctx, InputFile *file) {
return;
}
- if (ctx.arg.trace)
+ if (ctx.arg.getTrace())
Msg(ctx) << file;
if (file->kind() == InputFile::ObjKind) {
@@ -574,7 +574,7 @@ handleAArch64BAAndGnuProperties(ObjFile<ELFT> *file, Ctx &ctx,
template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
object::ELFFile<ELFT> obj = this->getObj();
// Read a section table. justSymbols is usually false.
- if (this->justSymbols) {
+ if (this->getJustSymbols()) {
initializeJustSymbols();
initializeSymbols(obj);
return;
@@ -608,7 +608,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
.second;
if (keepGroup) {
keptGroups.push_back(i);
- if (!ctx.arg.resolveGroups)
+ if (!ctx.arg.getResolveGroups())
sections[i] = createInputSection(
i, sec, check(obj.getSectionName(sec, shstrtab)));
} else {
@@ -623,7 +623,8 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
continue;
}
- if (sec.sh_type == SHT_LLVM_DEPENDENT_LIBRARIES && !ctx.arg.relocatable) {
+ if (sec.sh_type == SHT_LLVM_DEPENDENT_LIBRARIES &&
+ !ctx.arg.getRelocatable()) {
StringRef name = check(obj.getSectionName(sec, shstrtab));
ArrayRef<char> data = CHECK2(
this->getObj().template getSectionContentsAsArray<char>(sec), this);
@@ -647,7 +648,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
if (check(obj.getSectionName(sec, shstrtab)) == dynDbgSecName) {
sections[i] = &InputSection::discarded;
dynDbgSec = std::make_unique<InputSection>(*this, sec, dynDbgSecName);
- ctx.hasDynDbg = true;
+ ctx.setHasDynDbg(true);
}
continue;
}
@@ -724,7 +725,7 @@ bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &sec, StringRef name) {
// SHF_MERGE sections based both on their name and sh_entsize, but that seems
// to be more trouble than it is worth. Instead, we just use the regular (-O1)
// logic for -r.
- if (ctx.arg.optimize == 0 && !ctx.arg.relocatable)
+ if (ctx.arg.optimize == 0 && !ctx.arg.getRelocatable())
return false;
// A mergeable section with size 0 is useless because they don't have
@@ -795,7 +796,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
// SHF_EXCLUDE'ed sections are discarded by the linker. However,
// if -r is given, we'll let the final link discard such sections.
// This is compatible with GNU.
- if ((sec.sh_flags & SHF_EXCLUDE) && !ctx.arg.relocatable) {
+ if ((sec.sh_flags & SHF_EXCLUDE) && !ctx.arg.getRelocatable()) {
if (type == SHT_LLVM_CALL_GRAPH_PROFILE)
cgProfileSectionIndex = i;
if (type == SHT_LLVM_ADDRSIG) {
@@ -839,7 +840,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
}
switch (type) {
case SHT_GROUP: {
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
sections[i] = &InputSection::discarded;
// Use the verdict parse() recorded for this group instead of repeating
// the signature hashing and comdatGroups lookup.
@@ -874,7 +875,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
// The concatenated output does not properly reflect the linking
// semantics. In addition, since we do not use the bitcode wrapper format,
// the concatenated raw bitcode would be invalid.
- if (ctx.arg.relocatable && !ctx.arg.fatLTOObjects) {
+ if (ctx.arg.getRelocatable() && !ctx.arg.fatLTOObjects) {
sections[i] = &InputSection::discarded;
break;
}
@@ -882,7 +883,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
default:
this->sections[i] =
createInputSection(i, sec, check(obj.getSectionName(sec, shstrtab)));
- if (ctx.arg.rejectMismatch &&
+ if (ctx.arg.getRejectMismatch() &&
!isKnownSpecificSectionType(type, sec.sh_flags))
Err(ctx) << this->sections[i] << ": unknown section type 0x"
<< Twine::utohexstr(type);
@@ -935,7 +936,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
// `nullptr` for the normal case. However, if -r or --emit-relocs is
// specified, we need to copy them to the output. (Some post link analysis
// tools specify --emit-relocs to obtain the information.)
- if (ctx.arg.copyRelocs) {
+ if (ctx.arg.getCopyRelocs()) {
auto *isec = makeThreadLocal<InputSection>(
*this, sec, check(obj.getSectionName(sec, shstrtab)));
// If the relocated section is discarded (due to /DISCARD/ or
@@ -978,7 +979,8 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
handleAArch64BAAndGnuProperties<ELFT>(this, ctx, aarch64BAsubSections);
for (ArrayRef<Elf_Word> entries : selectedGroups)
- handleSectionGroup<ELFT>(this->sections, entries);
+ handleSectionGroup<ELFT>(ArrayRef<InputSectionBase *>(this->sections),
+ entries);
}
template <typename ELFT>
@@ -1133,7 +1135,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// an error if we encounter an executable .note.GNU-stack to force the
// user to explicitly request an executable stack.
if (name == ".note.GNU-stack") {
- if ((sec.sh_flags & SHF_EXECINSTR) && !ctx.arg.relocatable &&
+ if ((sec.sh_flags & SHF_EXECINSTR) && !ctx.arg.getRelocatable() &&
ctx.arg.zGnustack != GnuStackKind::Exec) {
Err(ctx) << this
<< ": requires an executable stack, but -z execstack is not "
@@ -1160,12 +1162,12 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// see https://gcc.gnu.org/wiki/SplitStacks. An object file compiled
// for split stack will include a .note.GNU-split-stack section.
if (name == ".note.GNU-split-stack") {
- if (ctx.arg.relocatable) {
+ if (ctx.arg.getRelocatable()) {
ErrAlways(ctx) << "cannot mix split-stack and non-split-stack in a "
"relocatable link";
return &InputSection::discarded;
}
- this->splitStack = true;
+ this->setSplitStack(true);
return &InputSection::discarded;
}
@@ -1173,7 +1175,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// functions were compiled with the no_split_stack_attribute will
// include a .note.GNU-no-split-stack section.
if (name == ".note.GNU-no-split-stack") {
- this->someNoSplitStack = true;
+ this->setSomeNoSplitStack(true);
return &InputSection::discarded;
}
@@ -1189,7 +1191,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// The linker merges EH (exception handling) frames and creates a
// .eh_frame_hdr section for runtime. So we handle them with a special
// class. For relocatable outputs, they are just passed through.
- if (name == ".eh_frame" && !ctx.arg.relocatable)
+ if (name == ".eh_frame" && !ctx.arg.getRelocatable())
return makeThreadLocal<EhInputSection>(*this, sec, name);
if ((sec.sh_flags & SHF_MERGE) && shouldMerge(sec, name))
@@ -1301,10 +1303,10 @@ template <class ELFT> void ObjFile<ELFT>::initDynDbgSymbols() {
setSymUsed(r.getSymbol(false));
} else if (sh.sh_type == SHT_RELA) {
for (const Elf_Rela &r : CHECK2(obj.relas(sh), &dbgObj))
- setSymUsed(r.getSymbol(ctx.arg.isMips64EL));
+ setSymUsed(r.getSymbol(ctx.arg.getIsMips64EL()));
} else {
for (const Elf_Rel &r : CHECK2(obj.rels(sh), &dbgObj))
- setSymUsed(r.getSymbol(ctx.arg.isMips64EL));
+ setSymUsed(r.getSymbol(ctx.arg.getIsMips64EL()));
}
}
@@ -1327,7 +1329,7 @@ template <class ELFT> void ObjFile<ELFT>::initDynDbgSymbols() {
template <class ELFT>
void ObjFile<ELFT>::initSectionsAndLocalSyms(bool ignoreComdats) {
- if (!justSymbols)
+ if (!getJustSymbols())
initializeSections(ignoreComdats, getObj());
if (!firstGlobal)
@@ -1822,10 +1824,10 @@ BitcodeFile::BitcodeFile(Ctx &ctx, MemoryBufferRef mb, StringRef archiveName,
uint64_t offsetInArchive, bool lazy)
: InputFile(ctx, BitcodeKind, mb) {
this->archiveName = archiveName;
- this->lazy = lazy;
+ this->setLazy(lazy);
std::string path = mb.getBufferIdentifier().str();
- if (ctx.arg.thinLTOIndexOnly)
+ if (ctx.arg.getThinLTOIndexOnly())
path = replaceThinLTOSuffix(ctx, mb.getBufferIdentifier());
// ThinLTO assumes that all MemoryBufferRefs given to it have a unique
@@ -2017,7 +2019,10 @@ std::unique_ptr<ELFFileBase> elf::createObjFile(Ctx &ctx, MemoryBufferRef mb,
llvm_unreachable("getELFKind");
}
f->init();
- f->lazy = lazy;
+ [&] {
+ auto PackedFlagValue_ = lazy;
+ return f->setLazy(PackedFlagValue_);
+ }();
return f;
}
@@ -2035,7 +2040,7 @@ template <class ELFT> void ObjFile<ELFT>::parseLazy() {
continue;
symbols[i] = symtab->insert(CHECK2(eSyms[i].getName(stringTable), this));
symbols[i]->resolve(ctx, LazySymbol{*this});
- if (!lazy)
+ if (!getLazy())
break;
}
}
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 5c4e060e2331b..d20c29715f66c 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -15,6 +15,7 @@
#include "lld/Common/LLVM.h"
#include "lld/Common/Reproduce.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/MemoryBufferRef.h"
@@ -54,7 +55,7 @@ class InputFile {
protected:
std::unique_ptr<Symbol *[]> symbols;
size_t numSymbols = 0;
- SmallVector<InputSectionBase *, 0> sections;
+ llvm::SmallVectorWithFlags<InputSectionBase *, 0, 3> sections;
public:
enum Kind : uint8_t {
@@ -108,7 +109,7 @@ class InputFile {
}
template <typename RelT> Symbol &getRelocTargetSym(const RelT &rel) const {
- uint32_t symIndex = rel.getSymbol(ctx.arg.isMips64EL);
+ uint32_t symIndex = rel.getSymbol(ctx.arg.getIsMips64EL());
return getSymbol(symIndex);
}
@@ -138,10 +139,12 @@ class InputFile {
// True if this is a relocatable object file/bitcode file in an ar archive
// or between --start-lib and --end-lib.
- bool lazy = false;
+ bool getLazy() const { return sections.getFlag(0); }
+ void setLazy(bool Value) { sections.setFlag(0, Value); }
// True if this is an argument for --just-symbols. Usually false.
- bool justSymbols = false;
+ bool getJustSymbols() const { return sections.getFlag(1); }
+ void setJustSymbols(bool Value) { sections.setFlag(1, Value); }
// On PPC64 we need to keep track of which files contain small code model
// relocations that access the .toc section. To minimize the chance of a
@@ -152,7 +155,11 @@ class InputFile {
// code model relocations support immediates in the range [-0x8000, 0x7FFC],
// making the addressable range relative to the toc pointer
// [.got, .got + 0xFFFC].
- bool ppc64SmallCodeModelTocRelocs = false;
+ bool getPpc64SmallCodeModelTocRelocs() const { return sections.getFlag(2); }
+ bool setPpc64SmallCodeModelTocRelocs(bool Value) {
+ sections.setFlag(2, Value);
+ return Value;
+ }
public:
// If not empty, this stores the name of the archive containing this file.
@@ -277,11 +284,13 @@ template <class ELFT> class ObjFile : public ELFFileBase {
// True if the file defines functions compiled with
// -fsplit-stack. Usually false.
- bool splitStack = false;
+ bool getSplitStack() const { return keptGroups.getFlag(0); }
+ void setSplitStack(bool Value) { keptGroups.setFlag(0, Value); }
// True if the file defines functions compiled with -fsplit-stack,
// but had one or more functions with the no_split_stack attribute.
- bool someNoSplitStack = false;
+ bool getSomeNoSplitStack() const { return keptGroups.getFlag(1); }
+ void setSomeNoSplitStack(bool Value) { keptGroups.setFlag(1, Value); }
void initDwarf();
@@ -318,7 +327,7 @@ template <class ELFT> class ObjFile : public ELFFileBase {
// Section indices of kept SHT_GROUP sections, recorded by parse() in
// ascending order, to be used by the parallel initializeSections().
- SmallVector<uint32_t, 0> keptGroups;
+ llvm::SmallVectorWithFlags<uint32_t, 0, 2> keptGroups;
};
class BitcodeFile : public InputFile {
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 13baaa5b8c2ad..0184d57e3931a 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -89,7 +89,7 @@ InputSectionBase::InputSectionBase(InputFile *file, StringRef name,
// --force-group-allocation, the SHF_GROUP flag and section groups are retained.
static uint64_t getFlags(Ctx &ctx, uint64_t flags) {
flags &= ~(uint64_t)SHF_INFO_LINK;
- if (ctx.arg.resolveGroups)
+ if (ctx.arg.getResolveGroups())
flags &= ~(uint64_t)SHF_GROUP;
return flags;
}
@@ -437,9 +437,10 @@ InputSectionBase *InputSection::getRelocatedSection() const {
template <class ELFT, class RelTy>
void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf) {
- bool linkerRelax =
- ctx.arg.relax && is_contained({EM_RISCV, EM_LOONGARCH}, ctx.arg.emachine);
- if (!ctx.arg.relocatable && (linkerRelax || ctx.arg.branchToBranch)) {
+ bool linkerRelax = ctx.arg.getRelax() &&
+ is_contained({EM_RISCV, EM_LOONGARCH}, ctx.arg.emachine);
+ if (!ctx.arg.getRelocatable() &&
+ (linkerRelax || ctx.arg.getBranchToBranch())) {
// On LoongArch and RISC-V, relaxation might change relocations: copy
// from internal ones that are updated by relaxation.
InputSectionBase *sec = getRelocatedSection();
@@ -454,8 +455,9 @@ void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf) {
const ObjFile<ELFT> &file;
Relocation operator()(const RelTy &rel) const {
// RelExpr is not used so set to a dummy value.
- return Relocation{R_NONE, rel.getType(ctx.arg.isMips64EL), rel.r_offset,
- getAddend<ELFT>(rel), &file.getRelocTargetSym(rel)};
+ return Relocation{R_NONE, rel.getType(ctx.arg.getIsMips64EL()),
+ rel.r_offset, getAddend<ELFT>(rel),
+ &file.getRelocTargetSym(rel)};
}
};
@@ -495,7 +497,7 @@ void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf,
// section, but for --emit-relocs it is a virtual address.
p->r_offset = sec->getVA(rel.offset);
p->setSymbolAndType(ctx.in.symTab->getSymbolIndex(sym), type,
- ctx.arg.isMips64EL);
+ ctx.arg.getIsMips64EL());
if (sym.type == STT_SECTION) {
// We combine multiple section symbols into only one per
@@ -556,7 +558,7 @@ void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf,
// writeSections will update the implicit addend. Non-SHF_ALLOC sections
// utilize relocateNonAlloc to process raw relocations and do not need
// this sec->relocations change.
- else if (ctx.arg.relocatable && (sec->flags & SHF_ALLOC) &&
+ else if (ctx.arg.getRelocatable() && (sec->flags & SHF_ALLOC) &&
type != target.noneRel)
sec->addReloc({R_ABS, type, rel.offset, addend, &sym});
} else if (ctx.arg.emachine == EM_PPC && type == R_PPC_PLTREL24 &&
@@ -1069,7 +1071,7 @@ void InputSection::relocateNonAlloc(Ctx &ctx, uint8_t *buf,
const InputFile *f = this->file;
for (auto it = rels.begin(), end = rels.end(); it != end; ++it) {
const RelTy &rel = *it;
- const RelType type = rel.getType(ctx.arg.isMips64EL);
+ const RelType type = rel.getType(ctx.arg.getIsMips64EL());
const uint64_t offset = rel.r_offset;
uint8_t *bufLoc = buf + offset;
int64_t addend = getAddend<ELFT>(rel);
@@ -1149,7 +1151,8 @@ void InputSection::relocateNonAlloc(Ctx &ctx, uint8_t *buf,
// explicit addend, such as RELA, remain unchanged and we can stop here.
// While content relocated by relocation types with an implicit addend, such
// as REL, needs the implicit addend updated.
- if (ctx.arg.relocatable && (RelTy::HasAddend || sym.type != STT_SECTION))
+ if (ctx.arg.getRelocatable() &&
+ (RelTy::HasAddend || sym.type != STT_SECTION))
continue;
// R_ABS/R_DTPREL and some other relocations can be used from non-SHF_ALLOC
@@ -1196,7 +1199,8 @@ void InputSection::relocateNonAlloc(Ctx &ctx, uint8_t *buf,
template <class ELFT>
void InputSection::relocate(Ctx &ctx, uint8_t *buf, uint8_t *bufEnd) {
- if ((flags & SHF_EXECINSTR) && LLVM_UNLIKELY(getFile<ELFT>()->splitStack))
+ if ((flags & SHF_EXECINSTR) &&
+ LLVM_UNLIKELY(getFile<ELFT>()->getSplitStack()))
adjustSplitStackFunctionPrologues<ELFT>(ctx, buf, bufEnd);
if (flags & SHF_ALLOC) {
@@ -1287,7 +1291,8 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(Ctx &ctx, uint8_t *buf,
// conservative.
if (Defined *d = dyn_cast<Defined>(rel.sym))
if (InputSection *isec = cast_or_null<InputSection>(d->section))
- if (!isec || !isec->getFile<ELFT>() || isec->getFile<ELFT>()->splitStack)
+ if (!isec || !isec->getFile<ELFT>() ||
+ isec->getFile<ELFT>()->getSplitStack())
continue;
if (enclosingPrologueAttempted(rel.offset, prologues))
@@ -1298,7 +1303,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(Ctx &ctx, uint8_t *buf,
if (ctx.target->adjustPrologueForCrossSplitStack(buf + f->value, end,
f->stOther))
continue;
- if (!getFile<ELFT>()->someNoSplitStack)
+ if (!getFile<ELFT>()->getSomeNoSplitStack())
Err(ctx)
<< this << ": " << f->getName() << " (with -fsplit-stack) calls "
<< rel.sym->getName()
@@ -1433,8 +1438,8 @@ void EhInputSection::preprocessRelocs(Relocs<RelTy> elfRels) {
rels.reserve(elfRels.size());
for (auto rel : elfRels) {
uint64_t offset = rel.r_offset;
- Symbol &sym = file->getSymbol(rel.getSymbol(ctx.arg.isMips64EL));
- RelType type = rel.getType(ctx.arg.isMips64EL);
+ Symbol &sym = file->getSymbol(rel.getSymbol(ctx.arg.getIsMips64EL()));
+ RelType type = rel.getType(ctx.arg.getIsMips64EL());
RelExpr expr = ctx.target->getRelExpr(type, sym, content().data() + offset);
int64_t addend =
RelTy::HasAddend
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index f5ce6f2c2fd4b..105385b847c72 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -100,9 +100,9 @@ static lto::Config createConfig(Ctx &ctx) {
if (auto relocModel = getRelocModelFromCMModel())
c.RelocModel = *relocModel;
- else if (ctx.arg.relocatable)
+ else if (ctx.arg.getRelocatable())
c.RelocModel = std::nullopt;
- else if (ctx.arg.isPic)
+ else if (ctx.arg.getIsPic())
c.RelocModel = Reloc::PIC_;
else
c.RelocModel = Reloc::Static;
@@ -125,7 +125,7 @@ static lto::Config createConfig(Ctx &ctx) {
// Set up optimization remarks if we've been asked to.
c.RemarksFilename = std::string(ctx.arg.optRemarksFilename);
c.RemarksPasses = std::string(ctx.arg.optRemarksPasses);
- c.RemarksWithHotness = ctx.arg.optRemarksWithHotness;
+ c.RemarksWithHotness = ctx.arg.getOptRemarksWithHotness();
c.RemarksHotnessThreshold = ctx.arg.optRemarksHotnessThreshold;
c.RemarksFormat = std::string(ctx.arg.optRemarksFormat);
@@ -141,14 +141,14 @@ static lto::Config createConfig(Ctx &ctx) {
c.HasWholeProgramVisibility = ctx.arg.ltoWholeProgramVisibility;
c.ValidateAllVtablesHaveTypeInfos =
ctx.arg.ltoValidateAllVtablesHaveTypeInfos;
- c.AllVtablesHaveTypeInfos = ctx.ltoAllVtablesHaveTypeInfos;
+ c.AllVtablesHaveTypeInfos = ctx.getLtoAllVtablesHaveTypeInfos();
c.AlwaysEmitRegularLTOObj = !ctx.arg.ltoObjPath.empty();
c.KeepSymbolNameCopies = false;
for (const llvm::StringRef &name : ctx.arg.thinLTOModulesToCompile)
c.ThinLTOModulesToCompile.emplace_back(name);
- c.TimeTraceEnabled = ctx.arg.timeTraceEnabled;
+ c.TimeTraceEnabled = ctx.arg.getTimeTraceEnabled();
c.TimeTraceGranularity = ctx.arg.timeTraceGranularity;
c.CSIRProfile = std::string(ctx.arg.ltoCSProfileFile);
@@ -184,7 +184,7 @@ BitcodeCompiler::BitcodeCompiler(Ctx &ctx) : ctx(ctx) {
// Initialize ltoObj.
lto::ThinBackend backend;
auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };
- if (ctx.arg.thinLTOIndexOnly) {
+ if (ctx.arg.getThinLTOIndexOnly()) {
backend = lto::createWriteIndexesThinBackend(
llvm::hardware_concurrency(ctx.arg.thinLTOJobs),
std::string(ctx.arg.thinLTOPrefixReplaceOld),
@@ -212,10 +212,12 @@ BitcodeCompiler::BitcodeCompiler(Ctx &ctx) : ctx(ctx) {
createConfig(ctx), ctx.arg.ltoPartitions, ltoModes[ctx.arg.ltoKind],
onIndexWrite, ctx.arg.thinLTOEmitIndexFiles,
ctx.arg.thinLTOEmitImportsFiles, ctx.arg.outputFile,
- ctx.arg.dtltoDistributor, ctx.arg.dtltoDistributorArgs,
- ctx.arg.dtltoCompiler, ctx.arg.dtltoCompilerPrependArgs,
- ctx.arg.dtltoCompilerArgs, createAddBufferFn(files, filenames),
- !ctx.arg.saveTempsArgs.empty());
+ ctx.arg.dtltoDistributor,
+ ArrayRef<StringRef>(ctx.arg.dtltoDistributorArgs),
+ ctx.arg.dtltoCompiler,
+ ArrayRef<StringRef>(ctx.arg.dtltoCompilerPrependArgs),
+ ArrayRef<StringRef>(ctx.arg.dtltoCompilerArgs),
+ createAddBufferFn(files, filenames), !ctx.arg.saveTempsArgs.empty());
// Initialize usedStartStop.
if (ctx.bitcodeFiles.empty())
return;
@@ -238,7 +240,7 @@ void BitcodeCompiler::waitForLTOCleanup() {
void BitcodeCompiler::add(BitcodeFile &f) {
lto::InputFile &obj = *f.obj;
- bool isExec = !ctx.arg.shared && !ctx.arg.relocatable;
+ bool isExec = !ctx.arg.getShared() && !ctx.arg.getRelocatable();
if (ctx.arg.thinLTOEmitIndexFiles)
thinIndices.insert(obj.getName());
@@ -268,10 +270,10 @@ void BitcodeCompiler::add(BitcodeFile &f) {
// 4) Symbols that are defined in bitcode files and used for dynamic
// linking.
// 5) Symbols that will be referenced after linker wrapping is performed.
- r.VisibleToRegularObj = ctx.arg.relocatable || sym->isUsedInRegularObj ||
- sym->referencedAfterWrap ||
- (r.Prevailing && sym->isExported) ||
- usedStartStop.contains(objSym.getSectionName());
+ r.VisibleToRegularObj =
+ ctx.arg.getRelocatable() || sym->isUsedInRegularObj ||
+ sym->referencedAfterWrap || (r.Prevailing && sym->isExported) ||
+ usedStartStop.contains(objSym.getSectionName());
// Identify symbols exported dynamically, and that therefore could be
// referenced by a shared library not visible to the linker.
r.ExportDynamic = sym->computeBinding(ctx) != STB_LOCAL &&
@@ -309,7 +311,7 @@ static void thinLTOCreateEmptyIndexFiles(Ctx &ctx) {
linkedBitCodeFiles.insert(f->getName());
for (BitcodeFile *f : ctx.lazyBitcodeFiles) {
- if (!f->lazy)
+ if (!f->getLazy())
continue;
if (linkedBitCodeFiles.contains(f->getName()))
continue;
@@ -367,7 +369,7 @@ SmallVector<std::unique_ptr<InputFile>, 0> BitcodeCompiler::compile() {
if (ctx.arg.thinLTOEmitIndexFiles)
thinLTOCreateEmptyIndexFiles(ctx);
- if (ctx.arg.thinLTOIndexOnly) {
+ if (ctx.arg.getThinLTOIndexOnly()) {
if (!ctx.arg.ltoObjPath.empty())
saveBuffer(buf[0].second, ctx.arg.ltoObjPath);
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index c69b0616a2367..eb16739dd585a 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -50,14 +50,14 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
// This is for --emit-relocs and -r. If .text.foo is emitted as .text.bar, we
// want to emit .rela.text.foo as .rela.text.bar for consistency (this is not
// technically required, but not doing it is odd). This code guarantees that.
- if (LLVM_UNLIKELY(ctx.arg.copyRelocs)) {
+ if (LLVM_UNLIKELY(ctx.arg.getCopyRelocs())) {
InputSectionBase *rel = nullptr;
if (auto *isec = dyn_cast<InputSection>(s))
rel = isec->getRelocatedSection();
if (rel) {
OutputSection *out = rel->getOutputSection();
if (!out) {
- assert(ctx.arg.relocatable && (rel->flags & SHF_LINK_ORDER));
+ assert(ctx.arg.getRelocatable() && (rel->flags & SHF_LINK_ORDER));
return s->name;
}
StringSaver &ss = ctx.saver;
@@ -69,7 +69,7 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
}
// Use default LLD behavior for the embedded unoptimized dynamic debugging
// relocatable link.
- if (ctx.arg.relocatable && !ctx.dynDbgRelocatable)
+ if (ctx.arg.getRelocatable() && !ctx.getDynDbgRelocatable())
return s->name;
}
@@ -78,7 +78,7 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
if (s->name == "COMMON")
return ".bss";
- if (hasSectionsCommand)
+ if (getHasSectionsCommand())
return s->name;
// When no SECTIONS is specified, emulate GNU ld's internal linker scripts
@@ -99,7 +99,7 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
// profile inaccuracy. Techniques such as hugepage remapping can make
// conservative decisions at the section granularity.
if (isSectionPrefix(".text", s->name)) {
- if (ctx.arg.zKeepTextSectionPrefix)
+ if (ctx.arg.getZKeepTextSectionPrefix())
for (StringRef v : {".text.hot", ".text.unknown", ".text.unlikely",
".text.startup", ".text.exit", ".text.split"})
if (isSectionPrefix(v.substr(5), s->name.substr(5)))
@@ -107,7 +107,7 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
return ".text";
}
if (isSectionPrefix(".ltext", s->name)) {
- if (ctx.arg.zKeepTextSectionPrefix)
+ if (ctx.arg.getZKeepTextSectionPrefix())
for (StringRef v : {".ltext.hot", ".ltext.unknown", ".ltext.unlikely",
".ltext.startup", ".ltext.exit", ".ltext.split"})
if (isSectionPrefix(v.substr(6), s->name.substr(6)))
@@ -134,7 +134,7 @@ StringRef LinkerScript::getOutputSectionName(const InputSectionBase *s) const {
// Note .bss.rel.ro doesn't have hot / unlikely mapping. It's placed before
// .bss so they get processed before `.bss` prefix is seen, just like
// how `.data.rel.ro` should be processed before seeing the `.data` prefix.
- if (ctx.arg.zKeepDataSectionPrefix)
+ if (ctx.arg.getZKeepDataSectionPrefix())
for (auto [index, v] : llvm::enumerate(dataSectionPrefixes)) {
StringRef secName = s->name;
// If v is the prefix, trim it from secName. Otherwise just continue to
@@ -241,7 +241,7 @@ void LinkerScript::expandMemoryRegions(uint64_t size) {
void LinkerScript::expandOutputSection(uint64_t size) {
state->outSec->size += size;
size_t regionSize = size;
- if (state->outSec->inOverlay) {
+ if (state->outSec->getInOverlay()) {
// Expand the overlay if necessary, and expand the region by the
// corresponding amount.
if (state->outSec->size > state->overlaySize) {
@@ -412,9 +412,10 @@ void LinkerScript::processInsertCommands() {
});
if (insertPos == sectionCommands.end()) {
ErrAlways(ctx) << "unable to insert " << cmd.names[0]
- << (cmd.isAfter ? " after " : " before ") << cmd.where;
+ << (cmd.getIsAfter() ? " after " : " before ")
+ << cmd.where;
} else {
- if (cmd.isAfter)
+ if (cmd.getIsAfter())
++insertPos;
sectionCommands.insert(insertPos, moves.begin(), moves.end());
}
@@ -688,7 +689,7 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
Err(ctx) << "undefined section class '" << cmd->classRef << "'";
return ret;
}
- if (!scd->sc.assigned) {
+ if (!scd->sc.getAssigned()) {
Err(ctx) << "section class '" << cmd->classRef << "' referenced by '"
<< outCmd.name << "' before class definition";
return ret;
@@ -852,7 +853,7 @@ void LinkerScript::processSectionCommands() {
s->parent = &sc->sc;
}
}
- sc->sc.assigned = true;
+ sc->sc.setAssigned(true);
}
}
@@ -1031,7 +1032,7 @@ static OutputDesc *addInputSec(Ctx &ctx,
if (sec->partition != isec->partition)
continue;
- if (ctx.arg.relocatable && (isec->flags & SHF_LINK_ORDER)) {
+ if (ctx.arg.getRelocatable() && (isec->flags & SHF_LINK_ORDER)) {
// Merging two SHF_LINK_ORDER sections with different sh_link fields will
// change their semantics, so we only merge them in -r links if they will
// end up being linked to the same output section. The casts are fine
@@ -1066,7 +1067,7 @@ void LinkerScript::addOrphanSections() {
if (name.empty())
name = getOutputSectionName(s);
- if (ctx.arg.unique) {
+ if (ctx.arg.getUnique()) {
v.push_back(createSection(ctx, s, name));
} else if (OutputSection *sec = findByName(sectionCommands, name)) {
sec->recordSection(s);
@@ -1079,8 +1080,8 @@ void LinkerScript::addOrphanSections() {
}
};
- const bool copyRelocs = ctx.arg.copyRelocs;
- const bool relocatable = ctx.arg.relocatable;
+ const bool copyRelocs = ctx.arg.getCopyRelocs();
+ const bool relocatable = ctx.arg.getRelocatable();
// Under --emit-relocs/-r, getOutputSectionName derives the name from the
// relocated section, and saving it is not thread-safe. Otherwise, the names
// can be precomputed in parallel.
@@ -1131,7 +1132,7 @@ void LinkerScript::addOrphanSections() {
// before others, so that we can handle scripts which refers them,
// for example: "foo = ABSOLUTE(ADDR(.text)));".
// When SECTIONS command is present we just add all orphans to the end.
- if (hasSectionsCommand)
+ if (getHasSectionsCommand())
sectionCommands.insert(sectionCommands.end(), v.begin(), v.end());
else
sectionCommands.insert(sectionCommands.begin(), v.begin(), v.end());
@@ -1140,7 +1141,7 @@ void LinkerScript::addOrphanSections() {
void LinkerScript::diagnoseOrphanHandling() const {
llvm::TimeTraceScope timeScope("Diagnose orphan sections");
if (ctx.arg.orphanHandling == OrphanHandlingPolicy::Place ||
- !hasSectionsCommand)
+ !getHasSectionsCommand())
return;
for (const InputSectionBase *sec : orphanSections) {
// .relro_padding is inserted before DATA_SEGMENT_RELRO_END, if present,
@@ -1182,7 +1183,7 @@ LinkerScript::findMemoryRegion(OutputSection *sec, MemoryRegion *hint) {
// Non-allocatable sections are not part of the process image.
if (!(sec->flags & SHF_ALLOC)) {
bool hasInputOrByteCommand =
- sec->hasInputSections ||
+ sec->getHasInputSections() ||
llvm::any_of(sec->commands, [](SectionCommand *comm) {
return ByteCommand::classof(comm);
});
@@ -1257,7 +1258,7 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
} else {
// If there is an explicit address expression this takes precedence over
// the memory region address.
- if (state->memRegion && !(hasSectionsCommand && sec->addrExpr))
+ if (state->memRegion && !(getHasSectionsCommand() && sec->addrExpr))
dot = state->memRegion->curPos;
if (sec->addrExpr)
setDot(sec->addrExpr, sec->location, false);
@@ -1272,7 +1273,7 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
}
state->outSec = sec;
- if (!(sec->addrExpr && hasSectionsCommand)) {
+ if (!(sec->addrExpr && getHasSectionsCommand())) {
// ALIGN is respected. sec->alignment is the max of ALIGN and the maximum of
// input section alignments.
const uint64_t pos = dot;
@@ -1307,11 +1308,12 @@ bool LinkerScript::assignOffsets(OutputSection *sec) {
// We can call this method multiple times during the creation of
// thunks and want to start over calculation each time.
sec->size = 0;
- if (sec->firstInOverlay)
+ if (sec->getFirstInOverlay())
state->overlaySize = 0;
bool synthesizeAlign =
- ctx.arg.relocatable && ctx.arg.relax && (sec->flags & SHF_EXECINSTR) &&
+ ctx.arg.getRelocatable() && ctx.arg.getRelax() &&
+ (sec->flags & SHF_EXECINSTR) &&
(ctx.arg.emachine == EM_LOONGARCH || ctx.arg.emachine == EM_RISCV);
// We visited SectionsCommands from processSectionCommands to
// layout sections. Now, we visit SectionsCommands again to fix
@@ -1387,13 +1389,13 @@ static bool isDiscardable(const OutputSection &sec) {
// We do not want to remove OutputSections with expressions that reference
// symbols even if the OutputSection is empty. We want to ensure that the
// expressions can be evaluated and report an error if they cannot.
- if (sec.expressionsUseSymbols)
+ if (sec.getExpressionsUseSymbols())
return false;
// OutputSections may be referenced by name in ADDR and LOADADDR expressions,
// as an empty Section can has a valid VMA and LMA we keep the OutputSection
// to maintain the integrity of the other Expression.
- if (sec.usedInExpression)
+ if (sec.getUsedInExpression())
return false;
for (SectionCommand *cmd : sec.commands) {
@@ -1463,14 +1465,14 @@ void LinkerScript::adjustOutputSections() {
// If sec has at least one input section and not discarded, remember its
// flags to be inherited by subsequent output sections. (sec may contain
// just one empty synthetic section.)
- if (sec->hasInputSections && !discardable)
+ if (sec->getHasInputSections() && !discardable)
flags = sec->flags;
// We do not want to keep any special flags for output section
// in case it is empty.
if (isEmpty) {
sec->flags =
- flags & ((sec->nonAlloc ? 0 : (uint64_t)SHF_ALLOC) | SHF_WRITE);
+ flags & ((sec->getNonAlloc() ? 0 : (uint64_t)SHF_ALLOC) | SHF_WRITE);
sec->sortRank = getSectionRank(ctx, *sec);
}
@@ -1496,8 +1498,8 @@ void LinkerScript::adjustOutputSections() {
sec->markDead();
cmd = nullptr;
} else {
- seenRelro |=
- sec->relro && !(sec->type == SHT_NOBITS && (sec->flags & SHF_TLS));
+ seenRelro |= sec->getRelro() &&
+ !(sec->type == SHT_NOBITS && (sec->flags & SHF_TLS));
}
}
@@ -1570,13 +1572,13 @@ void LinkerScript::allocateHeaders(
llvm::any_of(phdrsCommands, [](const PhdrsCommand &cmd) {
return cmd.hasPhdrs || cmd.hasFilehdr;
});
- bool paged = !ctx.arg.omagic && !ctx.arg.nmagic;
+ bool paged = !ctx.arg.getOmagic() && !ctx.arg.nmagic;
uint64_t headerSize = getHeaderSize(ctx);
uint64_t base = 0;
// If SECTIONS is present and the linkerscript is not explicit about program
// headers, only allocate program headers if that would not add a page.
- if (hasSectionsCommand && !hasExplicitHeaders)
+ if (getHasSectionsCommand() && !hasExplicitHeaders)
base = alignDown(min, ctx.arg.maxPageSize);
if ((paged || hasExplicitHeaders) && headerSize <= min - base) {
min = alignDown(min - headerSize, ctx.arg.maxPageSize);
@@ -1610,7 +1612,7 @@ LinkerScript::AddressState::AddressState(const LinkerScript &script) {
// that has changed its section or value (or nullptr if no symbol has changed).
std::pair<const OutputSection *, const Defined *>
LinkerScript::assignAddresses() {
- if (hasSectionsCommand) {
+ if (getHasSectionsCommand()) {
// With a linker script, assignment of addresses to headers is covered by
// allocateHeaders().
dot = ctx.arg.imageBase.value_or(0);
@@ -1625,7 +1627,7 @@ LinkerScript::assignAddresses() {
OutputSection *changedOsec = nullptr;
AddressState st(*this);
state = &st;
- errorOnMissingSection = true;
+ setErrorOnMissingSection(true);
st.outSec = aether.get();
recordedErrors.clear();
@@ -1850,7 +1852,7 @@ ExprValue LinkerScript::getSymbolValue(StringRef name, const Twine &loc) {
return v;
}
if (isa<SharedSymbol>(sym))
- if (!errorOnMissingSection)
+ if (!getErrorOnMissingSection())
return {nullptr, false, 0, loc};
}
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 80c4f564afabc..dd03d45078f09 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include <cstddef>
@@ -276,19 +277,27 @@ struct ByteCommand : SectionCommand {
};
struct InsertCommand {
- SmallVector<StringRef, 0> names;
- bool isAfter;
+ InsertCommand(SmallVector<StringRef, 0> names, bool isAfter, StringRef where)
+ : names(unsigned(isAfter), std::move(names)), where(where) {}
+ llvm::SmallVectorWithFlags<StringRef, 0> names;
+ bool getIsAfter() const { return names.getFlag(0); }
+ void setIsAfter(bool Value) { names.setFlag(0, Value); }
StringRef where;
};
// A NOCROSSREFS/NOCROSSREFS_TO command that prohibits references between
// certain output sections.
struct NoCrossRefCommand {
- SmallVector<StringRef, 0> outputSections;
+ llvm::SmallVectorWithFlags<StringRef, 0> outputSections;
+
+ NoCrossRefCommand() = default;
+ explicit NoCrossRefCommand(bool toFirst) {
+ outputSections.setFlag(0, toFirst);
+ }
// When true, this describes a NOCROSSREFS_TO command that probits references
// to the first output section from any of the other sections.
- bool toFirst = false;
+ bool toFirst() const { return outputSections.getFlag(0); }
};
struct PhdrsCommand {
@@ -417,10 +426,16 @@ class LinkerScript final {
// PHDRS command list.
SmallVector<PhdrsCommand, 0> phdrsCommands;
- bool hasSectionsCommand = false;
- bool seenDataAlign = false;
- bool seenRelroEnd = false;
- bool errorOnMissingSection = false;
+ bool getHasSectionsCommand() const { return orphanSections.getFlag(0); }
+ void setHasSectionsCommand(bool Value) { orphanSections.setFlag(0, Value); }
+ bool getSeenDataAlign() const { return orphanSections.getFlag(1); }
+ void setSeenDataAlign(bool Value) { orphanSections.setFlag(1, Value); }
+ bool getSeenRelroEnd() const { return orphanSections.getFlag(2); }
+ void setSeenRelroEnd(bool Value) { orphanSections.setFlag(2, Value); }
+ bool getErrorOnMissingSection() const { return orphanSections.getFlag(3); }
+ void setErrorOnMissingSection(bool Value) {
+ orphanSections.setFlag(3, Value);
+ }
SmallVector<SmallString<0>, 0> recordedErrors;
// List of section patterns specified with KEEP commands. They will
@@ -444,7 +459,7 @@ class LinkerScript final {
SmallVector<NoCrossRefCommand, 0> noCrossRefs;
// Sections that will be warned/errored by --orphan-handling.
- SmallVector<const InputSectionBase *, 0> orphanSections;
+ llvm::SmallVectorWithFlags<const InputSectionBase *, 0, 4> orphanSections;
// Stores the mapping: PROVIDE symbol -> symbols referred in the PROVIDE
// expression. For example, if the PROVIDE command is:
diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index 05ae25fc8efea..3261d2c3b50e6 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -45,7 +45,7 @@ static constexpr char indent16[] = " "; // 16 spaces
// Print out the first three columns of a line.
static void writeHeader(Ctx &ctx, raw_ostream &os, uint64_t vma, uint64_t lma,
uint64_t size, uint64_t align) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
os << format("%16llx %16llx %8llx %5lld ", vma, lma, size, align);
else
os << format("%8llx %8llx %8llx %5lld ", vma, lma, size, align);
@@ -154,7 +154,7 @@ static void writeMapFile(Ctx &ctx, raw_fd_ostream &os) {
DenseMap<Symbol *, std::string> symStr = getSymbolStrings(ctx, syms);
// Print out the header line.
- int w = ctx.arg.is64 ? 16 : 8;
+ int w = ctx.arg.getIs64() ? 16 : 8;
os << right_justify("VMA", w) << ' ' << right_justify("LMA", w)
<< " Size Align Out In Symbol\n";
@@ -259,7 +259,7 @@ static void writeCref(Ctx &ctx, raw_fd_ostream &os) {
}
void elf::writeMapAndCref(Ctx &ctx) {
- if (ctx.arg.mapFile.empty() && !ctx.arg.cref)
+ if (ctx.arg.mapFile.empty() && !ctx.arg.getCref())
return;
llvm::TimeTraceScope timeScope("Write map file");
@@ -275,6 +275,6 @@ void elf::writeMapAndCref(Ctx &ctx) {
if (!ctx.arg.mapFile.empty())
writeMapFile(ctx, os);
- if (ctx.arg.cref)
+ if (ctx.arg.getCref())
writeCref(ctx, os);
}
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index f5179bb2c60d0..badb43806efb2 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -94,7 +94,7 @@ template <class ELFT>
static uint64_t getAddend(Ctx &ctx, InputSectionBase &sec,
const typename ELFT::Rel &rel) {
return ctx.target->getImplicitAddend(sec.content().begin() + rel.r_offset,
- rel.getType(ctx.arg.isMips64EL));
+ rel.getType(ctx.arg.getIsMips64EL()));
}
template <class ELFT>
@@ -405,7 +405,7 @@ void MarkLive<ELFT, TrackWhyLive>::run() {
scanEhFrameSection(*eh);
// See markUsedSymbols.
bool markUsed =
- ctx.arg.copyRelocs &&
+ ctx.arg.getCopyRelocs() &&
(ctx.arg.discard != DiscardPolicy::None || ctx.arg.retainSymbols);
for (InputSectionBase *sec : ctx.inputSections) {
if (sec->flags & SHF_GNU_RETAIN) {
@@ -454,7 +454,8 @@ void MarkLive<ELFT, TrackWhyLive>::run() {
} else if (ctx.script->shouldKeep(sec)) {
enqueue(sec, /*offset=*/0, /*sym=*/nullptr,
{std::nullopt, "KEEP in linker script"});
- } else if ((!ctx.arg.zStartStopGC || sec->name.starts_with("__libc_")) &&
+ } else if ((!ctx.arg.getZStartStopGC() ||
+ sec->name.starts_with("__libc_")) &&
isValidCIdentifier(sec->name)) {
// As a workaround for glibc libc.a before 2.34
// (https://sourceware.org/PR27492), retain __libc_atexit and similar
@@ -622,7 +623,7 @@ template <class ELFT> void elf::markLive(Ctx &ctx) {
if (s->isUsedInRegularObj && !s->isWeak())
cast<SharedFile>(s->file)->isNeeded = true;
// See markUsedSymbols.
- if (ctx.arg.copyRelocs &&
+ if (ctx.arg.getCopyRelocs() &&
(ctx.arg.discard != DiscardPolicy::None || ctx.arg.retainSymbols))
parallelForEach(ctx.objectFiles, [](ELFFileBase *file) {
for (InputSectionBase *sec : file->getSections())
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 7ae024e47a7e8..6c8bcdda7c667 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -117,7 +117,7 @@ void OutputSection::recordSection(InputSectionBase *isec) {
// other InputSections.
void OutputSection::commitSection(InputSection *isec) {
if (LLVM_UNLIKELY(type != isec->type)) {
- if (!hasInputSections && !typeIsSet) {
+ if (!getHasInputSections() && !getTypeIsSet()) {
type = isec->type;
} else if (isStaticRelSecType(type) && isStaticRelSecType(isec->type) &&
(type == SHT_CREL) != (isec->type == SHT_CREL)) {
@@ -130,7 +130,7 @@ void OutputSection::commitSection(InputSection *isec) {
name = ctx.saver.save(".crel" + name);
}
} else {
- if (typeIsSet || !canMergeToProgbits(ctx, type) ||
+ if (getTypeIsSet() || !canMergeToProgbits(ctx, type) ||
!canMergeToProgbits(ctx, isec->type)) {
// The (NOLOAD) changes the section type to SHT_NOBITS, the intention is
// that the contents at that address is provided by some other means.
@@ -145,14 +145,14 @@ void OutputSection::commitSection(InputSection *isec) {
<< getELFSectionTypeName(ctx.arg.emachine, type);
}
}
- if (!typeIsSet)
+ if (!getTypeIsSet())
type = SHT_PROGBITS;
}
}
- if (!hasInputSections) {
+ if (!getHasInputSections()) {
// If IS is the first section to be added to this section,
// initialize type, entsize and flags from isec.
- hasInputSections = true;
+ setHasInputSections(true);
entsize = isec->entsize;
flags = isec->flags;
} else {
@@ -174,7 +174,7 @@ void OutputSection::commitSection(InputSection *isec) {
uint64_t andFlags = (flags & isec->flags) & andMask;
uint64_t orFlags = (flags | isec->flags) & orMask;
flags = andFlags | orFlags;
- if (nonAlloc)
+ if (getNonAlloc())
flags &= ~(uint64_t)SHF_ALLOC;
addralign = std::max(addralign, isec->addralign);
@@ -288,7 +288,7 @@ static void sortByOrder(MutableArrayRef<InputSection *> in,
}
uint64_t elf::getHeaderSize(Ctx &ctx) {
- if (ctx.arg.oFormatBinary)
+ if (ctx.arg.getOFormatBinary())
return 0;
return ctx.out.elfHeader->size + ctx.out.programHeaders->size;
}
@@ -548,8 +548,8 @@ void OutputSection::writeTo(Ctx &ctx, uint8_t *buf, parallel::TaskGroup &tg) {
// When in Arm BE8 mode, the linker has to convert the big-endian
// instructions to little-endian, leaving the data big-endian.
- if (ctx.arg.emachine == EM_ARM && !ctx.arg.isLE && ctx.arg.armBe8 &&
- (flags & SHF_EXECINSTR))
+ if (ctx.arg.emachine == EM_ARM && !ctx.arg.getIsLE() &&
+ ctx.arg.getArmBe8() && (flags & SHF_EXECINSTR))
convertArmInstructionstoBE8(ctx, isec, buf + isec->outSecOff);
// Fill gaps between sections.
@@ -684,7 +684,7 @@ static size_t relToCrel(Ctx &ctx, raw_svector_ostream &os,
for (auto rel : rels) {
encodeOneCrel<typename ELFT::uint>(
ctx, os, out, sec->getVA(rel.r_offset), file.getRelocTargetSym(rel),
- rel.getType(ctx.arg.isMips64EL), getAddend<ELFT>(rel));
+ rel.getType(ctx.arg.getIsMips64EL()), getAddend<ELFT>(rel));
}
return rels.size();
}
@@ -713,11 +713,11 @@ template <bool is64> void OutputSection::finalizeNonAllocCrel(Ctx &ctx) {
// Convert REL[A] to CREL.
if constexpr (is64) {
- totalCount += ctx.arg.isLE
+ totalCount += ctx.arg.getIsLE()
? relToCrel<ELF64LE>(ctx, os, out, relSec, sec)
: relToCrel<ELF64BE>(ctx, os, out, relSec, sec);
} else {
- totalCount += ctx.arg.isLE
+ totalCount += ctx.arg.getIsLE()
? relToCrel<ELF32LE>(ctx, os, out, relSec, sec)
: relToCrel<ELF32BE>(ctx, os, out, relSec, sec);
}
@@ -747,7 +747,7 @@ void OutputSection::finalize(Ctx &ctx) {
return;
}
- if (!ctx.arg.copyRelocs || !isStaticRelSecType(type))
+ if (!ctx.arg.getCopyRelocs() || !isStaticRelSecType(type))
return;
// Skip if 'first' is synthetic, i.e. not a section created by --emit-relocs.
@@ -765,7 +765,7 @@ void OutputSection::finalize(Ctx &ctx) {
flags |= SHF_INFO_LINK;
// Finalize the content of non-alloc CREL.
if (type == SHT_CREL) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
finalizeNonAllocCrel<true>(ctx);
else
finalizeNonAllocCrel<false>(ctx);
@@ -848,26 +848,6 @@ InputSection *elf::getFirstInputSection(const OutputSection *os) {
return nullptr;
}
-ArrayRef<InputSection *>
-elf::getInputSections(const OutputSection &os,
- SmallVector<InputSection *, 0> &storage) {
- ArrayRef<InputSection *> ret;
- storage.clear();
- for (SectionCommand *cmd : os.commands) {
- auto *isd = dyn_cast<InputSectionDescription>(cmd);
- if (!isd)
- continue;
- if (ret.empty()) {
- ret = isd->sections;
- } else {
- if (storage.empty())
- storage.assign(ret.begin(), ret.end());
- storage.insert(storage.end(), isd->sections.begin(), isd->sections.end());
- }
- }
- return storage.empty() ? ret : ArrayRef(storage);
-}
-
// Sorts input sections by section name suffixes, so that .foo.N comes
// before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
// We want to keep the original order if the priorities are the same
@@ -884,7 +864,7 @@ std::array<uint8_t, 4> OutputSection::getFiller(Ctx &ctx) {
return *filler;
if (!(flags & SHF_EXECINSTR))
return {0, 0, 0, 0};
- if (ctx.arg.relocatable && ctx.arg.emachine == EM_RISCV) {
+ if (ctx.arg.getRelocatable() && ctx.arg.emachine == EM_RISCV) {
// See RISCV::maybeSynthesizeAlign: Synthesized NOP bytes and ALIGN
// relocations might be needed between two input sections. Use a NOP for the
// filler.
@@ -892,13 +872,13 @@ std::array<uint8_t, 4> OutputSection::getFiller(Ctx &ctx) {
return {1, 0, 1, 0};
return {0x13, 0, 0, 0};
}
- if (ctx.arg.relocatable && ctx.arg.emachine == EM_LOONGARCH)
+ if (ctx.arg.getRelocatable() && ctx.arg.emachine == EM_LOONGARCH)
return {0, 0, 0x40, 0x03};
return ctx.target->trapInstr;
}
void OutputSection::checkDynRelAddends(Ctx &ctx) {
- assert(ctx.arg.writeAddends && ctx.arg.checkDynamicRelocs);
+ assert(ctx.arg.writeAddends && ctx.arg.getCheckDynamicRelocs());
assert(isStaticRelSecType(type));
SmallVector<InputSection *, 0> storage;
ArrayRef<InputSection *> sections = getInputSections(*this, storage);
@@ -927,7 +907,7 @@ void OutputSection::checkDynRelAddends(Ctx &ctx) {
// With -z mark-plt, the JUMP_SLOT relocation's addend is the PLT entry
// address, but the .got.plt entry it targets holds the lazy-binding
// address instead, so the written value intentionally differs.
- if (ctx.arg.zMarkPlt && rel.type == ctx.target->pltRel)
+ if (ctx.arg.getZMarkPlt() && rel.type == ctx.target->pltRel)
continue;
const uint8_t *relocTarget =
ctx.bufferStart + relOsec->offset + (rel.r_offset - relOsec->addr);
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 77654f85ca78c..7afb0b65bc0aa 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -12,6 +12,7 @@
#include "InputSection.h"
#include "LinkerScript.h"
#include "lld/Common/LLVM.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Parallel.h"
@@ -90,28 +91,48 @@ class OutputSection final : public SectionBase {
uint64_t crelHeader = 0;
SmallVector<char, 0> crelBody;
- SmallVector<SectionCommand *, 0> commands;
+ llvm::SmallVectorWithFlags<SectionCommand *, 0, 4> commands;
SmallVector<StringRef, 0> phdrs;
std::optional<std::array<uint8_t, 4>> filler;
ConstraintKind constraint = ConstraintKind::NoConstraint;
std::string location;
std::string memoryRegionName;
std::string lmaRegionName;
- bool nonAlloc = false;
- bool typeIsSet = false;
- bool expressionsUseSymbols = false;
- bool usedInExpression = false;
- bool inOverlay = false;
- bool firstInOverlay = false;
+ bool getNonAlloc() const { return storage.getFlag(0); }
+ void setNonAlloc(bool Value) { storage.setFlag(0, Value); }
+ bool getTypeIsSet() const { return storage.getFlag(1); }
+ void setTypeIsSet(bool Value) { storage.setFlag(1, Value); }
+ bool getExpressionsUseSymbols() const { return storage.getFlag(2); }
+ bool setExpressionsUseSymbols(bool Value) {
+ storage.setFlag(2, Value);
+ return Value;
+ }
+ bool getUsedInExpression() const { return storage.getFlag(3); }
+ bool setUsedInExpression(bool Value) {
+ storage.setFlag(3, Value);
+ return Value;
+ }
+ bool getInOverlay() const { return commands.getFlag(0); }
+ void setInOverlay(bool Value) { commands.setFlag(0, Value); }
+ bool getFirstInOverlay() const { return commands.getFlag(1); }
+ bool setFirstInOverlay(bool Value) {
+ commands.setFlag(1, Value);
+ return Value;
+ }
// Tracks whether the section has ever had an input section added to it, even
// if the section was later removed (e.g. because it is a synthetic section
// that wasn't needed). This is needed for orphan placement.
- bool hasInputSections = false;
+ bool getHasInputSections() const { return commands.getFlag(2); }
+ void setHasInputSections(bool Value) { commands.setFlag(2, Value); }
// The output section description is specified between DATA_SEGMENT_ALIGN and
// DATA_RELRO_END.
- bool relro = false;
+ bool getRelro() const { return commands.getFlag(3); }
+ bool setRelro(bool Value) {
+ commands.setFlag(3, Value);
+ return Value;
+ }
template <bool is64> void finalizeNonAllocCrel(Ctx &);
void finalize(Ctx &);
@@ -132,7 +153,7 @@ class OutputSection final : public SectionBase {
CompressedData compressed;
private:
- SmallVector<InputSection *, 0> storage;
+ llvm::SmallVectorWithFlags<InputSection *, 0, 4> storage;
};
struct OutputDesc final : SectionCommand {
@@ -149,8 +170,9 @@ struct OutputDesc final : SectionCommand {
// section descriptions. If referenced more than once, the sections can be
// spilled to the next reference like --enable-non-contiguous-regions.
struct SectionClass final : public SectionBase {
- SmallVector<InputSectionDescription *, 0> commands;
- bool assigned = false;
+ llvm::SmallVectorWithFlags<InputSectionDescription *, 0> commands;
+ bool getAssigned() const { return commands.getFlag(0); }
+ void setAssigned(bool Value) { commands.setFlag(0, Value); }
SectionClass(StringRef name)
: SectionBase(Class, nullptr, name, 0, 0, 0, 0, 0, 0) {}
@@ -168,9 +190,25 @@ struct SectionClassDesc : SectionCommand {
int getPriority(StringRef s);
InputSection *getFirstInputSection(const OutputSection *os);
-llvm::ArrayRef<InputSection *>
-getInputSections(const OutputSection &os,
- SmallVector<InputSection *, 0> &storage);
+template <typename StorageT>
+ArrayRef<InputSection *> getInputSections(const OutputSection &os,
+ StorageT &storage) {
+ ArrayRef<InputSection *> ret;
+ storage.clear();
+ for (SectionCommand *cmd : os.commands) {
+ auto *isd = dyn_cast<InputSectionDescription>(cmd);
+ if (!isd)
+ continue;
+ if (ret.empty()) {
+ ret = isd->sections;
+ } else {
+ if (storage.empty())
+ storage.assign(ret.begin(), ret.end());
+ storage.insert(storage.end(), isd->sections.begin(), isd->sections.end());
+ }
+ }
+ return storage.empty() ? ret : ArrayRef(storage);
+}
uint64_t getHeaderSize(Ctx &);
} // namespace lld::elf
diff --git a/lld/ELF/RelocScan.h b/lld/ELF/RelocScan.h
index ca55577e9ee71..79570dbfa3d6f 100644
--- a/lld/ELF/RelocScan.h
+++ b/lld/ELF/RelocScan.h
@@ -78,7 +78,7 @@ class RelocScan {
void processR_PC(RelType type, uint64_t offset, int64_t addend, Symbol &sym) {
if (LLVM_UNLIKELY(sym.isGnuIFunc()))
sym.setFlags(HAS_DIRECT_RELOC);
- if (sym.isPreemptible || (isAbsolute(sym) && ctx.arg.isPic))
+ if (sym.isPreemptible || (isAbsolute(sym) && ctx.arg.getIsPic()))
processAux(R_PC, type, offset, sym, addend);
else
sec->addReloc({R_PC, type, offset, addend, &sym});
@@ -96,7 +96,7 @@ class RelocScan {
if (sym.isPreemptible) {
sym.setFlags(NEEDS_PLT);
sec->addReloc({R_PLT_PC, type, offset, addend, &sym});
- } else if (!(isAbsolute(sym) && ctx.arg.isPic)) {
+ } else if (!(isAbsolute(sym) && ctx.arg.getIsPic())) {
sec->addReloc({R_PC, type, offset, addend, &sym});
} else {
processAux(R_PC, type, offset, sym, addend);
@@ -107,14 +107,14 @@ class RelocScan {
template <bool enableIeToLe = true>
void handleTlsIe(RelExpr ieExpr, RelType type, uint64_t offset,
int64_t addend, Symbol &sym) {
- if (enableIeToLe && !ctx.arg.shared && !sym.isPreemptible) {
+ if (enableIeToLe && !ctx.arg.getShared() && !sym.isPreemptible) {
// Optimize to Local Exec.
sec->addReloc({R_TPREL, type, offset, addend, &sym});
} else {
sym.setFlags(NEEDS_TLSIE);
// R_GOT (absolute GOT address) needs a RELATIVE dynamic relocation in
// PIC when the relocation uses the full address (not just low page bits).
- if (ieExpr == R_GOT && ctx.arg.isPic &&
+ if (ieExpr == R_GOT && ctx.arg.getIsPic() &&
!ctx.target->usesOnlyLowPageBits(type))
ctx.in.relaDyn->addRelativeReloc<true>(ctx.target->relativeRel, *sec,
offset, sym, addend, type,
@@ -128,7 +128,7 @@ class RelocScan {
// call should be skipped (i.e., caller should ++it).
bool handleTlsLd(RelExpr sharedExpr, RelType type, uint64_t offset,
int64_t addend, Symbol &sym) {
- if (ctx.arg.shared) {
+ if (ctx.arg.getShared()) {
ctx.needsTlsLd.store(true, std::memory_order_relaxed);
sec->addReloc({sharedExpr, type, offset, addend, &sym});
return false;
@@ -143,7 +143,7 @@ class RelocScan {
// ieExpr/leExpr to disable GD-to-IE/LE optimization (e.g. ARM, RISC-V).
bool handleTlsGd(RelExpr sharedExpr, RelExpr ieExpr, RelExpr leExpr,
RelType type, uint64_t offset, int64_t addend, Symbol &sym) {
- if (!ctx.arg.shared && ieExpr != R_NONE) {
+ if (!ctx.arg.getShared() && ieExpr != R_NONE) {
if (sym.isPreemptible) {
// Optimize to Initial Exec.
sym.setFlags(NEEDS_TLSIE);
@@ -162,7 +162,7 @@ class RelocScan {
// Handle TLSDESC relocation.
void handleTlsDesc(RelExpr sharedExpr, RelExpr ieExpr, RelType type,
uint64_t offset, int64_t addend, Symbol &sym) {
- if (ctx.arg.shared) {
+ if (ctx.arg.getShared()) {
sym.setFlags(NEEDS_TLSDESC);
sec->addReloc({sharedExpr, type, offset, addend, &sym});
} else if (sym.isPreemptible) {
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index db5ba7d023b7f..39527bd5f4b43 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -620,14 +620,14 @@ static void reportUndefinedSymbol(Ctx &ctx, const UndefinedDiag &undef,
msg << "\n>>> the vtable symbol may be undefined because the class is "
"missing its key function "
"(see https://lld.llvm.org/missingkeyfunction)";
- if (ctx.arg.gcSections && ctx.arg.zStartStopGC &&
+ if (ctx.arg.gcSections && ctx.arg.getZStartStopGC() &&
sym.getName().starts_with("__start_")) {
msg << "\n>>> the encapsulation symbol needs to be retained under "
"--gc-sections properly; consider -z nostart-stop-gc "
"(see https://lld.llvm.org/ELF/start-stop-gc)";
}
- if (undef.isWarning)
+ if (undef.getIsWarning())
Warn(ctx) << msg.str();
else
ctx.e.error(msg.str(), ErrorTag::SymbolNotFound, {sym.getName()});
@@ -694,7 +694,7 @@ bool RelocScan::maybeReportUndefined(Undefined &sym, uint64_t offset) {
}
bool RelocScan::checkTlsLe(uint64_t offset, Symbol &sym, RelType type) {
- if (!ctx.arg.shared)
+ if (!ctx.arg.getShared())
return false;
auto diag = Err(ctx);
diag << "relocation " << type << " against " << &sym
@@ -762,7 +762,7 @@ static void addPltEntry(Ctx &ctx, PltSection &plt, GotPltSection &gotPlt,
return;
}
gotPlt.addEntry(sym);
- if (sym.isPreemptible && ctx.arg.zMarkPlt && type == ctx.target->pltRel)
+ if (sym.isPreemptible && ctx.arg.getZMarkPlt() && type == ctx.target->pltRel)
expr = R_PLT;
rel.addReloc(
{type, &gotPlt, sym.getGotPltOffset(ctx), isPreemptible, sym, 0, expr});
@@ -781,7 +781,7 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
// Otherwise, the value is either a link-time constant or the load base
// plus a constant.
- if (!ctx.arg.isPic || isAbsolute(sym))
+ if (!ctx.arg.getIsPic() || isAbsolute(sym))
ctx.in.got->addConstant({R_ABS, ctx.target->symbolicRel, off, 0, &sym});
else
addRelativeReloc(ctx, *ctx.in.got, off, sym, 0, R_ABS,
@@ -810,7 +810,7 @@ static void addGotAuthEntry(Ctx &ctx, Symbol &sym) {
static void addTpOffsetGotEntry(Ctx &ctx, Symbol &sym) {
ctx.in.got->addEntry(sym);
uint64_t off = sym.getGotOffset(ctx);
- if (!sym.isPreemptible && !ctx.arg.shared) {
+ if (!sym.isPreemptible && !ctx.arg.getShared()) {
ctx.in.got->addConstant({R_TPREL, ctx.target->symbolicRel, off, 0, &sym});
return;
}
@@ -863,7 +863,7 @@ bool RelocScan::isStaticLinkTimeConstant(RelExpr e, RelType type,
// These never do, except if the entire file is position dependent or if
// only the low bits are used.
if (e == R_GOT || e == R_PLT)
- return ctx.target->usesOnlyLowPageBits(type) || !ctx.arg.isPic;
+ return ctx.target->usesOnlyLowPageBits(type) || !ctx.arg.getIsPic();
// R_AARCH64_AUTH_ABS64 requires a dynamic relocation unless the symbol is
// non-preemptible and undefined.
if (e == RE_AARCH64_AUTH && (!sym.isUndefined() || sym.isPreemptible))
@@ -878,8 +878,8 @@ bool RelocScan::isStaticLinkTimeConstant(RelExpr e, RelType type,
// IRELATIVE). Emitting dynamic relocations for -shared aligns with its -z
// undefs default. Dynamic -no-pie linking and -pie allow flexibility.
if (sym.isPreemptible)
- return sym.isUndefined() && !ctx.arg.isPic;
- if (!ctx.arg.isPic)
+ return sym.isUndefined() && !ctx.arg.getIsPic();
+ if (!ctx.arg.getIsPic())
return true;
// Constant when referencing a non-preemptible symbol.
@@ -951,7 +951,7 @@ void RelocScan::process(RelExpr expr, RelType type, uint64_t offset,
// We were asked not to generate PLT entries for ifuncs. Instead, pass the
// direct relocation on through.
- if (LLVM_UNLIKELY(isIfunc) && ctx.arg.zIfuncNoplt) {
+ if (LLVM_UNLIKELY(isIfunc) && ctx.arg.getZIfuncNoplt()) {
std::lock_guard<std::mutex> lock(ctx.relocMutex);
sym.isExported = true;
ctx.in.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
@@ -1003,7 +1003,7 @@ void RelocScan::processAux(RelExpr expr, RelType type, uint64_t offset,
// For MIPS, we don't implement GNU ld's DW_EH_PE_absptr to DW_EH_PE_pcrel
// conversion. We still emit a dynamic relocation.
bool canWrite = (sec->flags & SHF_WRITE) ||
- !(ctx.arg.zText ||
+ !(ctx.arg.getZText() ||
(isa<EhInputSection>(sec) && ctx.arg.emachine != EM_MIPS));
if (canWrite) {
RelType rel = ctx.target->getDynRel(type);
@@ -1062,7 +1062,7 @@ void RelocScan::processAux(RelExpr expr, RelType type, uint64_t offset,
// STT_OBJECT) and canonical PLT (for STT_FUNC) if sym is defined by a DSO.
// Copy relocations/canonical PLT entries are unsupported for
// R_AARCH64_AUTH_ABS64.
- if (!ctx.arg.shared && sym.isShared() &&
+ if (!ctx.arg.getShared() && sym.isShared() &&
!(ctx.arg.emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
if (!canDefineSymbolInExecutable(ctx, sym)) {
auto diag = Err(ctx);
@@ -1114,7 +1114,7 @@ void RelocScan::processAux(RelExpr expr, RelType type, uint64_t offset,
// * If a library definition gets preempted to the executable, it will have
// the wrong ebx value.
if (sym.isFunc()) {
- if (ctx.arg.pie && ctx.arg.emachine == EM_386) {
+ if (ctx.arg.getPie() && ctx.arg.emachine == EM_386) {
auto diag = Err(ctx);
diag << "symbol '" << &sym
<< "' cannot be preempted; recompile with -fPIE";
@@ -1252,7 +1252,7 @@ static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) {
//
// Note: IRELATIVE relocations are needed even in static executables; see
// `addRelIpltSymbols`.
- if (!sym.isGnuIFunc() || sym.isPreemptible || ctx.arg.zIfuncNoplt)
+ if (!sym.isGnuIFunc() || sym.isPreemptible || ctx.arg.getZIfuncNoplt())
return false;
// Skip unreferenced non-preemptible ifunc.
if (!(flags & (NEEDS_GOT | NEEDS_GOT_AUTH | NEEDS_PLT | HAS_DIRECT_RELOC)))
@@ -1390,7 +1390,7 @@ void elf::postScanRelocations(Ctx &ctx) {
ctx.in.relaDyn->addSymbolReloc(ctx.target->tlsOffsetRel, *got,
offsetOff, sym);
} else {
- if (ctx.arg.shared)
+ if (ctx.arg.getShared())
ctx.in.relaDyn->addReloc({ctx.target->tlsModuleIndexRel, got, off});
else
// Write one to the GOT slot.
@@ -1414,7 +1414,7 @@ void elf::postScanRelocations(Ctx &ctx) {
GotSection *got = ctx.in.got.get();
if (ctx.needsTlsLd.load(std::memory_order_relaxed) && got->addTlsIndex()) {
- if (ctx.arg.shared)
+ if (ctx.arg.getShared())
ctx.in.relaDyn->addReloc(
{ctx.target->tlsModuleIndexRel, got, got->getTlsIndexOff()});
else
@@ -1435,7 +1435,7 @@ void elf::postScanRelocations(Ctx &ctx) {
if (needsTlsIe)
ctx.hasTlsIe.store(true, std::memory_order_relaxed);
- if (ctx.arg.branchToBranch)
+ if (ctx.arg.getBranchToBranch())
ctx.target->applyBranchToBranchOpt();
}
@@ -1801,7 +1801,7 @@ ThunkSection *ThunkCreator::addThunkSection(OutputSection *os,
isd->sections.back()->getSize() -
isd->sections.front()->outSecOff;
if (os->size > ctx.target->getThunkSectionSpacing() && isdSize > 4096)
- ts->roundUpSizeForErrata = true;
+ ts->setRoundUpSizeForErrata(true);
}
isd->thunkSections.push_back({ts, pass});
return ts;
@@ -1820,7 +1820,7 @@ static bool isThunkSectionCompatible(InputSection *source, Thunk &thunk) {
// Thunks in a different Overlay Output Section can't be reused
// as we can't guarantee that the Overlay will be in memory.
- return (sourceOS == targetOS || !targetOS->inOverlay);
+ return (sourceOS == targetOS || !targetOS->getInOverlay());
}
std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
@@ -2008,7 +2008,7 @@ bool ThunkCreator::createThunks(uint32_t pass,
}
static bool matchesRefTo(const NoCrossRefCommand &cmd, StringRef osec) {
- if (cmd.toFirst)
+ if (cmd.toFirst())
return cmd.outputSections[0] == osec;
return llvm::is_contained(cmd.outputSections, osec);
}
@@ -2017,7 +2017,7 @@ template <class ELFT, class Rels>
static void scanCrossRefs(Ctx &ctx, const NoCrossRefCommand &cmd,
OutputSection *osec, InputSection *sec, Rels rels) {
for (const auto &r : rels) {
- Symbol &sym = sec->file->getSymbol(r.getSymbol(ctx.arg.isMips64EL));
+ Symbol &sym = sec->file->getSymbol(r.getSymbol(ctx.arg.getIsMips64EL()));
// A legal cross-reference is when the destination output section is
// nullptr, osec for a self-reference, or a section that is described by the
// NOCROSSREFS/NOCROSSREFS_TO command.
@@ -2042,7 +2042,7 @@ template <class ELFT> void elf::checkNoCrossRefs(Ctx &ctx) {
for (OutputSection *osec : ctx.outputSections) {
for (const NoCrossRefCommand &noxref : ctx.script->noCrossRefs) {
if (!llvm::is_contained(noxref.outputSections, osec->name) ||
- (noxref.toFirst && noxref.outputSections[0] == osec->name))
+ (noxref.toFirst() && noxref.outputSections[0] == osec->name))
continue;
for (SectionCommand *cmd : osec->commands) {
auto *isd = dyn_cast<InputSectionDescription>(cmd);
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 0c54fde488292..7e6962d960e4f 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -306,7 +306,7 @@ void ScriptParser::readDefsym() {
void ScriptParser::readNoCrossRefs(bool to) {
expect("(");
- NoCrossRefCommand cmd{{}, to};
+ NoCrossRefCommand cmd(to);
while (auto tok = till(")"))
cmd.outputSections.push_back(unquote(tok));
if (cmd.outputSections.size() < 2)
@@ -502,11 +502,11 @@ void ScriptParser::readOutputFormat() {
if (!consume(")")) {
expect(",");
StringRef tmp = readName();
- if (ctx.arg.optEB)
+ if (ctx.arg.getOptEB())
s = tmp;
expect(",");
tmp = readName();
- if (ctx.arg.optEL)
+ if (ctx.arg.getOptEL())
s = tmp;
consume(")");
}
@@ -516,7 +516,7 @@ void ScriptParser::readOutputFormat() {
ctx.arg.bfdname = s;
if (s == "binary") {
- ctx.arg.oFormatBinary = true;
+ ctx.arg.setOFormatBinary(true);
return;
}
@@ -573,7 +573,7 @@ void ScriptParser::readRegionAlias() {
void ScriptParser::readSearchDir() {
expect("(");
StringRef name = readName();
- if (!ctx.arg.nostdlib)
+ if (!ctx.arg.getNostdlib())
ctx.arg.searchPaths.push_back(name);
expect(")");
}
@@ -605,14 +605,14 @@ SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
osd->osec.lmaExpr = lmaExpr;
// Use first section address for subsequent sections. Ensure the first
// section, even if empty, is not discarded.
- osd->osec.usedInExpression = true;
+ osd->osec.setUsedInExpression(true);
addrExpr = [=]() -> ExprValue { return {&osd->osec, false, 0, ""}; };
}
v.push_back(osd);
prev = &osd->osec;
}
if (!v.empty())
- static_cast<OutputDesc *>(v.front())->osec.firstInOverlay = true;
+ static_cast<OutputDesc *>(v.front())->osec.setFirstInOverlay(true);
if (consume(">")) {
StringRef regionName = readName();
for (SectionCommand *od : v)
@@ -682,16 +682,16 @@ void ScriptParser::readSections() {
// If DATA_SEGMENT_RELRO_END is absent, for sections after DATA_SEGMENT_ALIGN,
// the relro fields should be cleared.
- if (!ctx.script->seenRelroEnd)
+ if (!ctx.script->getSeenRelroEnd())
for (SectionCommand *cmd : v)
if (auto *osd = dyn_cast<OutputDesc>(cmd))
- osd->osec.relro = false;
+ osd->osec.setRelro(false);
ctx.script->sectionCommands.insert(ctx.script->sectionCommands.end(),
v.begin(), v.end());
if (atEOF() || !consume("INSERT")) {
- ctx.script->hasSectionsCommand = true;
+ ctx.script->setHasSectionsCommand(true);
return;
}
@@ -955,7 +955,7 @@ bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok) {
if (consume("NOLOAD")) {
cmd->type = SHT_NOBITS;
- cmd->typeIsSet = true;
+ cmd->setTypeIsSet(true);
} else if (consume("TYPE")) {
expect("=");
StringRef value = peek();
@@ -970,10 +970,10 @@ bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok) {
// Otherwise, read an expression.
cmd->type = readExpr()().getValue();
}
- cmd->typeIsSet = true;
+ cmd->setTypeIsSet(true);
} else {
skip(); // This is "COPY", "INFO" or "OVERLAY".
- cmd->nonAlloc = true;
+ cmd->setNonAlloc(true);
}
expect(")");
return true;
@@ -1024,7 +1024,7 @@ static Expr checkAlignment(Ctx &ctx, Expr e, std::string &loc) {
OutputDesc *ScriptParser::readOverlaySectionDescription() {
OutputDesc *osd =
ctx.script->createOutputSection(readName(), getCurrentLocation());
- osd->osec.inOverlay = true;
+ osd->osec.setInOverlay(true);
expect("{");
while (auto tok = till("}"))
readOutputSectionStmt(osd->osec, tok);
@@ -1037,7 +1037,8 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
ctx.script->createOutputSection(unquote(outSec), getCurrentLocation());
OutputSection *osec = &cmd->osec;
// Maybe relro. Will reset to false if DATA_SEGMENT_RELRO_END is absent.
- osec->relro = ctx.script->seenDataAlign && !ctx.script->seenRelroEnd;
+ osec->setRelro(ctx.script->getSeenDataAlign() &&
+ !ctx.script->getSeenRelroEnd());
size_t symbolsReferenced = ctx.script->referencedSymbols.size();
@@ -1087,7 +1088,7 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
consume(",");
if (ctx.script->referencedSymbols.size() > symbolsReferenced)
- osec->expressionsUseSymbols = true;
+ osec->setExpressionsUseSymbols(true);
return cmd;
}
@@ -1190,7 +1191,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
const char *oldS = prevTok.data();
SymbolAssignment *cmd = nullptr;
- bool savedSeenRelroEnd = ctx.script->seenRelroEnd;
+ bool savedSeenRelroEnd = ctx.script->getSeenRelroEnd();
const StringRef op = peek();
{
SaveAndRestore saved(lexState, State::Expr);
@@ -1210,7 +1211,8 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
}
if (cmd) {
- cmd->dataSegmentRelroEnd = !savedSeenRelroEnd && ctx.script->seenRelroEnd;
+ cmd->dataSegmentRelroEnd =
+ !savedSeenRelroEnd && ctx.script->getSeenRelroEnd();
cmd->commandString = StringRef(oldS, curTok.data() - oldS).str();
squeezeSpaces(cmd->commandString);
expect(";");
@@ -1495,7 +1497,7 @@ StringRef ScriptParser::readParenName() {
static void checkIfExists(LinkerScript &script, const OutputSection &osec,
StringRef location) {
- if (osec.location.empty() && script.errorOnMissingSection)
+ if (osec.location.empty() && script.getErrorOnMissingSection())
script.recordError(location + ": undefined section " + osec.name);
}
@@ -1541,7 +1543,7 @@ Expr ScriptParser::readPrimary() {
if (tok == "ADDR") {
StringRef name = readParenName();
OutputSection *osec = &ctx.script->getOrCreateOutputSection(name)->osec;
- osec->usedInExpression = true;
+ osec->setUsedInExpression(true);
return [=, s = ctx.script]() -> ExprValue {
checkIfExists(*s, *osec, location);
return {osec, false, 0, location};
@@ -1583,7 +1585,7 @@ Expr ScriptParser::readPrimary() {
expect(",");
readExpr();
expect(")");
- ctx.script->seenDataAlign = true;
+ ctx.script->setSeenDataAlign(true);
return [=, s = ctx.script] {
uint64_t align = std::max(uint64_t(1), e().getValue());
return (s->getDot() + align - 1) & -align;
@@ -1604,7 +1606,7 @@ Expr ScriptParser::readPrimary() {
expect(",");
readExpr();
expect(")");
- ctx.script->seenRelroEnd = true;
+ ctx.script->setSeenRelroEnd(true);
return [&ctx = this->ctx] {
return alignToPowerOf2(ctx.script->getDot(), ctx.arg.maxPageSize);
};
@@ -1631,7 +1633,7 @@ Expr ScriptParser::readPrimary() {
if (tok == "LOADADDR") {
StringRef name = readParenName();
OutputSection *osec = &ctx.script->getOrCreateOutputSection(name)->osec;
- osec->usedInExpression = true;
+ osec->setUsedInExpression(true);
return [=, s = ctx.script] {
checkIfExists(*s, *osec, location);
return osec->getLMA();
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index d9ced6f24bd8b..21bcf4120f002 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -49,7 +49,7 @@ void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) {
// keep sym if it was defined, otherwise it's unused and can be dropped.
sym->isUsedInRegularObj = false;
- if (ctx.hasDynDbg) {
+ if (ctx.getHasDynDbg()) {
if (sym->isDynDbgRef)
wrap->isDynDbgRef = true;
if (real->isDynDbgRef)
@@ -222,7 +222,7 @@ void SymbolTable::scanVersionScript() {
found |= !findByVersion({(pat.name + "@" + v.name).toStringRef(buf),
pat.isExternCpp, /*hasWildCard=*/false})
.empty();
- if (!found && !ctx.arg.undefinedVersion)
+ if (!found && !ctx.arg.getUndefinedVersion())
Err(ctx) << "version script assignment of '" << ver << "' to symbol '"
<< pat.name << "' failed: symbol not defined";
};
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index e7b8153ca36b2..6fd6eab3ce11f 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -127,7 +127,7 @@ static uint64_t getSymVA(Ctx &ctx, const Symbol &sym, int64_t addend) {
((sym.stOther & STO_MIPS_MICROMIPS) || sym.hasFlag(NEEDS_COPY)))
va |= 1;
- if (d.isTls() && !ctx.arg.relocatable) {
+ if (d.isTls() && !ctx.arg.getRelocatable()) {
// Use the address of the TLS segment's first section rather than the
// segment's address, because segment addresses aren't initialized until
// after sections are finalized. (e.g. Measuring the size of .rela.dyn
@@ -274,14 +274,14 @@ void Symbol::parseSymbolVersion(Ctx &ctx) {
// so we do not report error in this case. We also do not error
// if the symbol has a local version as it won't be in the dynamic
// symbol table.
- if (ctx.arg.shared && versionId != VER_NDX_LOCAL)
+ if (ctx.arg.getShared() && versionId != VER_NDX_LOCAL)
ErrAlways(ctx) << file << ": symbol " << s << " has undefined version "
<< verstr;
}
void Symbol::extract(Ctx &ctx) const {
- assert(file->lazy);
- file->lazy = false;
+ assert(file->getLazy());
+ file->setLazy(false);
parseFile(ctx, file);
}
@@ -368,14 +368,14 @@ bool elf::computeIsPreemptible(Ctx &ctx, const Symbol &sym) {
if (!sym.isDefined())
return !sym.isUndefined() || ctx.arg.zDynamicUndefined;
- if (!ctx.arg.shared)
+ if (!ctx.arg.getShared())
return false;
// If -Bsymbolic or --dynamic-list is specified, or -Bsymbolic-functions is
// specified and the symbol is STT_FUNC, the symbol is preemptible iff it is
// in the dynamic list. -Bsymbolic-non-weak-functions is a non-weak subset of
// -Bsymbolic-functions.
- if (ctx.arg.symbolic ||
+ if (ctx.arg.getSymbolic() ||
(ctx.arg.bsymbolic == BsymbolicKind::NonWeak &&
sym.binding != STB_WEAK) ||
(ctx.arg.bsymbolic == BsymbolicKind::Functions && sym.isFunc()) ||
@@ -498,7 +498,8 @@ void Symbol::resolve(Ctx &ctx, const Undefined &other) {
// A forms group 0. B form group 1. C and D (including their member object
// files) form group 2. E forms group 3. I think that you can see how this
// group assignment rule simulates the traditional linker's semantics.
- bool backref = ctx.arg.warnBackrefs && file->groupId < other.file->groupId;
+ bool backref =
+ ctx.arg.getWarnBackrefs() && file->groupId < other.file->groupId;
extract(ctx);
if (!ctx.arg.whyExtract.empty())
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index f59e676c2e6f5..9baf14fdbfd3f 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -55,11 +55,11 @@ using llvm::support::endian::write32le;
using llvm::support::endian::write64le;
static uint64_t readUint(Ctx &ctx, uint8_t *buf) {
- return ctx.arg.is64 ? read64(ctx, buf) : read32(ctx, buf);
+ return ctx.arg.getIs64() ? read64(ctx, buf) : read32(ctx, buf);
}
static void writeUint(Ctx &ctx, uint8_t *buf, uint64_t val) {
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write64(ctx, buf, val);
else
write32(ctx, buf, val);
@@ -108,7 +108,7 @@ Defined *elf::addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type,
if (ctx.in.symTab)
ctx.in.symTab->addSymbol(s);
- if (ctx.arg.emachine == EM_ARM && !ctx.arg.isLE && ctx.arg.armBe8 &&
+ if (ctx.arg.emachine == EM_ARM && !ctx.arg.getIsLE() && ctx.arg.getArmBe8() &&
(section.flags & SHF_EXECINSTR))
// Adding Linker generated mapping symbols to the arm specific mapping
// symbols list.
@@ -177,7 +177,7 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
write32(ctx, buf + offset + 0, featureAndType); // Feature type
write32(ctx, buf + offset + 4, 4); // Feature size
write32(ctx, buf + offset + 8, ctx.arg.andFeatures); // Feature flags
- if (ctx.arg.is64)
+ if (ctx.arg.getIs64())
write32(ctx, buf + offset + 12, 0); // Padding
offset += 16;
}
@@ -193,7 +193,7 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
size_t GnuPropertySection::getSize() const {
uint32_t contentSize = 0;
if (ctx.arg.andFeatures != 0)
- contentSize += ctx.arg.is64 ? 16 : 12;
+ contentSize += ctx.arg.getIs64() ? 16 : 12;
if (ctx.aarch64PauthAbiCoreInfo)
contentSize += 4 + 4 + AArch64PauthAbiCoreInfo::size();
assert(contentSize != 0);
@@ -395,7 +395,7 @@ void EhFrameSection::writeTo(uint8_t *buf) {
return;
// Write the .eh_frame_hdr section using cached FDE data from updateAllocSize.
- bool large = hdr->large;
+ bool large = hdr->getLarge();
int64_t ehFramePtr = getParent()->addr - hdr->getVA() - 4;
auto writeField = [&](uint8_t *buf, uint64_t val) {
large ? write64(ctx, buf, val) : write32(ctx, buf, val);
@@ -438,7 +438,7 @@ void EhFrameHeader::finalizeContents() {
// Initially `large` is false; updateAllocSize may set it to true if addresses
// exceed the 32-bit range, then call finalizeContents again.
auto numFdes = ctx.in.ehFrame->numFdes;
- size = 4 + (large ? 8 : 4) + 4 + numFdes * (large ? 16 : 8);
+ size = 4 + (getLarge() ? 8 : 4) + 4 + numFdes * (getLarge() ? 16 : 8);
}
bool EhFrameHeader::updateAllocSize(Ctx &ctx) {
@@ -486,7 +486,7 @@ bool EhFrameHeader::updateAllocSize(Ctx &ctx) {
fdes.end());
ehFrame->numFdes = fdes.size();
- large = newLarge;
+ setLarge(newLarge);
// Compute size.
size_t oldSize = size;
@@ -906,7 +906,7 @@ void MipsGotSection::build() {
// When building a shared library we still need a dynamic relocation
// for the TP-relative offset as we don't know how much other data will
// be allocated before us in the static TLS block.
- if (!s->isPreemptible && !ctx.arg.shared)
+ if (!s->isPreemptible && !ctx.arg.getShared())
addConstant({R_TPREL, ctx.target->symbolicRel, offset, 0, s});
else
ctx.in.relaDyn->addAddendOnlyRelocIfNonPreemptible(
@@ -916,7 +916,7 @@ void MipsGotSection::build() {
Symbol *s = p.first;
uint64_t off = p.second * ctx.arg.wordsize;
if (s == nullptr) {
- if (ctx.arg.shared)
+ if (ctx.arg.getShared())
ctx.in.relaDyn->addReloc({ctx.target->tlsModuleIndexRel, this, off});
else
addConstant(
@@ -935,7 +935,7 @@ void MipsGotSection::build() {
ctx.in.relaDyn->addSymbolReloc(ctx.target->tlsOffsetRel, *this,
offsetOff, *s);
} else {
- if (ctx.arg.shared)
+ if (ctx.arg.getShared())
ctx.in.relaDyn->addReloc(
{ctx.target->tlsModuleIndexRel, this, off});
else
@@ -972,7 +972,7 @@ void MipsGotSection::build() {
for (size_t pi = 0; pi < pageCount; ++pi) {
uint64_t offset = (l.second.firstIndex + pi) * ctx.arg.wordsize;
int64_t addend = int64_t(pi * 0x10000);
- if (!ctx.arg.isPic || &got == primGot)
+ if (!ctx.arg.getIsPic() || &got == primGot)
addConstant({RE_MIPS_OSEC_LOCAL_PAGE, ctx.target->relativeRel, offset,
addend, l.second.repSym});
else
@@ -986,7 +986,7 @@ void MipsGotSection::build() {
if (p.first.first == nullptr)
addConstant({R_ADDEND, ctx.target->relativeRel, offset, p.first.second,
ctx.dummySym});
- else if (!ctx.arg.isPic || &got == primGot)
+ else if (!ctx.arg.getIsPic() || &got == primGot)
addConstant({R_ABS, ctx.target->relativeRel, offset, p.first.second,
p.first.first});
else
@@ -1000,7 +1000,7 @@ void MipsGotSection::build() {
bool MipsGotSection::isNeeded() const {
// We add the .got section to the result for dynamic MIPS target because
// its address and properties are mentioned in the .dynamic section.
- return !ctx.arg.relocatable;
+ return !ctx.arg.getRelocatable();
}
uint64_t MipsGotSection::getGp(const InputFile *f) const {
@@ -1112,7 +1112,7 @@ void IgotPltSection::writeTo(uint8_t *buf) {
StringTableSection::StringTableSection(Ctx &ctx, StringRef name, bool dynamic)
: SyntheticSection(ctx, name, SHT_STRTAB, dynamic ? (uint64_t)SHF_ALLOC : 0,
1),
- dynamic(dynamic) {
+ strings(decltype(this->strings)::withFlags(unsigned(dynamic))) {
// ELF string tables start with a NUL byte.
strings.push_back("");
stringMap.try_emplace(CachedHashStringRef(""), 0);
@@ -1162,7 +1162,7 @@ DynamicSection<ELFT>::DynamicSection(Ctx &ctx)
// which passes -z rodynamic.
// See "Special Section" in Chapter 4 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- if (ctx.arg.emachine == EM_MIPS || ctx.arg.zRodynamic)
+ if (ctx.arg.emachine == EM_MIPS || ctx.arg.getZRodynamic())
this->flags = SHF_ALLOC;
}
@@ -1220,31 +1220,31 @@ DynamicSection<ELFT>::computeContents() {
uint32_t dtFlags1 = 0;
if (ctx.arg.bsymbolic == BsymbolicKind::All)
dtFlags |= DF_SYMBOLIC;
- if (ctx.arg.zGlobal)
+ if (ctx.arg.getZGlobal())
dtFlags1 |= DF_1_GLOBAL;
- if (ctx.arg.zInitfirst)
+ if (ctx.arg.getZInitfirst())
dtFlags1 |= DF_1_INITFIRST;
- if (ctx.arg.zInterpose)
+ if (ctx.arg.getZInterpose())
dtFlags1 |= DF_1_INTERPOSE;
- if (ctx.arg.zNodefaultlib)
+ if (ctx.arg.getZNodefaultlib())
dtFlags1 |= DF_1_NODEFLIB;
- if (ctx.arg.zNodelete)
+ if (ctx.arg.getZNodelete())
dtFlags1 |= DF_1_NODELETE;
- if (ctx.arg.zNodlopen)
+ if (ctx.arg.getZNodlopen())
dtFlags1 |= DF_1_NOOPEN;
- if (ctx.arg.pie)
+ if (ctx.arg.getPie())
dtFlags1 |= DF_1_PIE;
- if (ctx.arg.zNow) {
+ if (ctx.arg.getZNow()) {
dtFlags |= DF_BIND_NOW;
dtFlags1 |= DF_1_NOW;
}
- if (ctx.arg.zOrigin) {
+ if (ctx.arg.getZOrigin()) {
dtFlags |= DF_ORIGIN;
dtFlags1 |= DF_1_ORIGIN;
}
- if (!ctx.arg.zText)
+ if (!ctx.arg.getZText())
dtFlags |= DF_TEXTREL;
- if (ctx.hasTlsIe && ctx.arg.shared)
+ if (ctx.hasTlsIe && ctx.arg.getShared())
dtFlags |= DF_STATIC_TLS;
if (dtFlags)
@@ -1260,7 +1260,8 @@ DynamicSection<ELFT>::computeContents() {
// systems (currently only Fuchsia OS) provide other means to give the
// debugger this information. Such systems may choose make .dynamic read-only.
// If the target is such a system (used -z rodynamic) don't write DT_DEBUG.
- if (!ctx.arg.shared && !ctx.arg.relocatable && !ctx.arg.zRodynamic)
+ if (!ctx.arg.getShared() && !ctx.arg.getRelocatable() &&
+ !ctx.arg.getZRodynamic())
addInt(DT_DEBUG, 0);
if (ctx.in.relaDyn->isNeeded()) {
@@ -1268,7 +1269,7 @@ DynamicSection<ELFT>::computeContents() {
entries.emplace_back(ctx.in.relaDyn->sizeDynamicTag,
addRelaSz(ctx, *ctx.in.relaDyn));
- bool isRela = ctx.arg.isRela;
+ bool isRela = ctx.arg.getIsRela();
addInt(isRela ? DT_RELAENT : DT_RELENT,
isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
@@ -1283,11 +1284,11 @@ DynamicSection<ELFT>::computeContents() {
}
if (ctx.in.relrDyn && ctx.in.relrDyn->getParent() &&
!ctx.in.relrDyn->relocs.empty()) {
- addInSec(ctx.arg.useAndroidRelrTags ? DT_ANDROID_RELR : DT_RELR,
+ addInSec(ctx.arg.getUseAndroidRelrTags() ? DT_ANDROID_RELR : DT_RELR,
*ctx.in.relrDyn);
- addInt(ctx.arg.useAndroidRelrTags ? DT_ANDROID_RELRSZ : DT_RELRSZ,
+ addInt(ctx.arg.getUseAndroidRelrTags() ? DT_ANDROID_RELRSZ : DT_RELRSZ,
ctx.in.relrDyn->getParent()->size);
- addInt(ctx.arg.useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
+ addInt(ctx.arg.getUseAndroidRelrTags() ? DT_ANDROID_RELRENT : DT_RELRENT,
sizeof(Elf_Relr));
}
if (ctx.in.relrAuthDyn && ctx.in.relrAuthDyn->getParent() &&
@@ -1330,10 +1331,10 @@ DynamicSection<ELFT>::computeContents() {
addInSec(DT_PLTGOT, *ctx.in.gotPlt);
break;
}
- addInt(DT_PLTREL, ctx.arg.isRela ? DT_RELA : DT_REL);
+ addInt(DT_PLTREL, ctx.arg.getIsRela() ? DT_RELA : DT_REL);
}
- if (ctx.arg.zMarkPlt && ctx.in.plt->isNeeded()) {
+ if (ctx.arg.getZMarkPlt() && ctx.in.plt->isNeeded()) {
addInSec(DT_X86_64_PLT, *ctx.in.plt);
addInt(DT_X86_64_PLTSZ, ctx.in.plt->getSize());
addInt(DT_X86_64_PLTENT, ctx.target->pltEntrySize);
@@ -1342,7 +1343,7 @@ DynamicSection<ELFT>::computeContents() {
if (ctx.arg.emachine == EM_AARCH64) {
if (ctx.arg.andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
addInt(DT_AARCH64_BTI_PLT, 0);
- if (ctx.arg.zPacPlt)
+ if (ctx.arg.getZPacPlt())
addInt(DT_AARCH64_PAC_PLT, 0);
if (hasMemtag(ctx)) {
@@ -1362,7 +1363,7 @@ DynamicSection<ELFT>::computeContents() {
addInt(DT_SYMENT, sizeof(Elf_Sym));
addInSec(DT_STRTAB, *ctx.in.dynStrTab);
addInt(DT_STRSZ, ctx.in.dynStrTab->getSize());
- if (!ctx.arg.zText)
+ if (!ctx.arg.getZText())
addInt(DT_TEXTREL, 0);
if (ctx.in.gnuHashTab && ctx.in.gnuHashTab->getParent())
addInSec(DT_GNU_HASH, *ctx.in.gnuHashTab);
@@ -1417,7 +1418,7 @@ DynamicSection<ELFT>::computeContents() {
addInt(DT_MIPS_GOTSYM, ctx.in.dynSymTab->getNumSymbols());
addInSec(DT_PLTGOT, *ctx.in.mipsGot);
if (ctx.in.mipsRldMap) {
- if (!ctx.arg.pie)
+ if (!ctx.arg.getPie())
addInSec(DT_MIPS_RLD_MAP, *ctx.in.mipsRldMap);
// Store the offset to the .rld_map section
// relative to the address of the tag.
@@ -1470,7 +1471,7 @@ int64_t DynamicReloc::computeAddend(Ctx &ctx) const {
assert(!isFinal && "addend already computed");
uint64_t ca = inputSec->getRelocTargetVA(
ctx, Relocation{expr, type, 0, addend, sym}, getOffset());
- return ctx.arg.is64 ? ca : SignExtend64<32>(ca);
+ return ctx.arg.getIs64() ? ca : SignExtend64<32>(ca);
}
uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const {
@@ -1592,11 +1593,11 @@ void RelocationBaseSection::computeRels() {
template <class ELFT>
RelocationSection<ELFT>::RelocationSection(Ctx &ctx, StringRef name,
bool combreloc, unsigned concurrency)
- : RelocationBaseSection(ctx, name, ctx.arg.isRela ? SHT_RELA : SHT_REL,
- ctx.arg.isRela ? DT_RELA : DT_REL,
- ctx.arg.isRela ? DT_RELASZ : DT_RELSZ, combreloc,
- concurrency) {
- this->entsize = ctx.arg.isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+ : RelocationBaseSection(ctx, name, ctx.arg.getIsRela() ? SHT_RELA : SHT_REL,
+ ctx.arg.getIsRela() ? DT_RELA : DT_REL,
+ ctx.arg.getIsRela() ? DT_RELASZ : DT_RELSZ,
+ combreloc, concurrency) {
+ this->entsize = ctx.arg.getIsRela() ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
@@ -1606,10 +1607,10 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
llvm::concat<const DynamicReloc>(relativeRelocs, relocs)) {
auto *p = reinterpret_cast<Elf_Rela *>(buf);
p->r_offset = rel.r_offset;
- p->setSymbolAndType(rel.r_sym, rel.type, ctx.arg.isMips64EL);
- if (ctx.arg.isRela)
+ p->setSymbolAndType(rel.r_sym, rel.type, ctx.arg.getIsMips64EL());
+ if (ctx.arg.getIsRela())
p->r_addend = rel.addend;
- buf += ctx.arg.isRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+ buf += ctx.arg.getIsRela() ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
}
}
@@ -1619,7 +1620,7 @@ RelrBaseSection::RelrBaseSection(Ctx &ctx, unsigned concurrency,
ctx, isAArch64Auth ? ".relr.auth.dyn" : ".relr.dyn",
isAArch64Auth
? SHT_AARCH64_AUTH_RELR
- : (ctx.arg.useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR),
+ : (ctx.arg.getUseAndroidRelrTags() ? SHT_ANDROID_RELR : SHT_RELR),
SHF_ALLOC, ctx.arg.wordsize),
relocsVec(concurrency) {}
@@ -1639,9 +1640,9 @@ template <class ELFT>
AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection(
Ctx &ctx, StringRef name, unsigned concurrency)
: RelocationBaseSection(
- ctx, name, ctx.arg.isRela ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
- ctx.arg.isRela ? DT_ANDROID_RELA : DT_ANDROID_REL,
- ctx.arg.isRela ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ,
+ ctx, name, ctx.arg.getIsRela() ? SHT_ANDROID_RELA : SHT_ANDROID_REL,
+ ctx.arg.getIsRela() ? DT_ANDROID_RELA : DT_ANDROID_REL,
+ ctx.arg.getIsRela() ? DT_ANDROID_RELASZ : DT_ANDROID_RELSZ,
/*combreloc=*/false, concurrency) {
this->entsize = 1;
}
@@ -1710,7 +1711,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
Elf_Rela r;
r.r_offset = rel.getOffset();
r.setSymbolAndType(rel.getSymIndex(symTab), rel.type, false);
- r.r_addend = ctx.arg.isRela ? rel.computeAddend(ctx) : 0;
+ r.r_addend = ctx.arg.getIsRela() ? rel.computeAddend(ctx) : 0;
return r;
};
std::vector<Elf_Rela> relatives, nonRelatives;
@@ -1777,9 +1778,9 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
for (auto i = nonRelatives.begin(), e = nonRelatives.end(); i != e;) {
auto j = i + 1;
while (j != e && i->r_info == j->r_info &&
- (!ctx.arg.isRela || i->r_addend == j->r_addend))
+ (!ctx.arg.getIsRela() || i->r_addend == j->r_addend))
++j;
- if (j - i < 3 || (ctx.arg.isRela && i->r_addend != 0))
+ if (j - i < 3 || (ctx.arg.getIsRela() && i->r_addend != 0))
ungroupedNonRelatives.insert(ungroupedNonRelatives.end(), i, j);
else
nonRelativeGroups.emplace_back(i, j);
@@ -1792,7 +1793,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
});
unsigned hasAddendIfRela =
- ctx.arg.isRela ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
+ ctx.arg.getIsRela() ? RELOCATION_GROUP_HAS_ADDEND_FLAG : 0;
uint64_t offset = 0;
uint64_t addend = 0;
@@ -1809,7 +1810,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
add(g[0].r_offset - offset);
add(ctx.target->relativeRel);
- if (ctx.arg.isRela) {
+ if (ctx.arg.getIsRela()) {
add(g[0].r_addend - addend);
addend = g[0].r_addend;
}
@@ -1820,7 +1821,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
RELOCATION_GROUPED_BY_INFO_FLAG | hasAddendIfRela);
add(ctx.arg.wordsize);
add(ctx.target->relativeRel);
- if (ctx.arg.isRela) {
+ if (ctx.arg.getIsRela()) {
for (const auto &i : llvm::drop_begin(g)) {
add(i.r_addend - addend);
addend = i.r_addend;
@@ -1838,7 +1839,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
for (Elf_Rela &r : ungroupedRelatives) {
add(r.r_offset - offset);
offset = r.r_offset;
- if (ctx.arg.isRela) {
+ if (ctx.arg.getIsRela()) {
add(r.r_addend - addend);
addend = r.r_addend;
}
@@ -1865,7 +1866,7 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize(Ctx &ctx) {
add(r.r_offset - offset);
offset = r.r_offset;
add(r.r_info);
- if (ctx.arg.isRela) {
+ if (ctx.arg.getIsRela()) {
add(r.r_addend - addend);
addend = r.r_addend;
}
@@ -2144,7 +2145,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
buf += sizeof(Elf_Sym);
auto *eSym = reinterpret_cast<Elf_Sym *>(buf);
- bool relocatable = ctx.arg.relocatable;
+ bool relocatable = ctx.arg.getRelocatable();
for (SymbolTableEntry &ent : symbols) {
Symbol *sym = ent.sym;
// Set st_name, st_info and st_other.
@@ -2199,7 +2200,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
eSym->st_other |= STO_MIPS_MICROMIPS;
}
}
- if (ctx.arg.relocatable)
+ if (ctx.arg.getRelocatable())
if (auto *d = dyn_cast<Defined>(sym))
if (isMipsPIC<ELFT>(d))
eSym->st_other |= STO_MIPS_PIC;
@@ -2219,7 +2220,7 @@ void SymtabShndxSection::writeTo(uint8_t *buf) {
// SHN_XINDEX, we need to write actual index, otherwise, we must write
// SHN_UNDEF(0).
buf += 4; // Ignore .symtab[0] entry.
- bool relocatable = ctx.arg.relocatable;
+ bool relocatable = ctx.arg.getRelocatable();
for (const SymbolTableEntry &entry : ctx.in.symTab->getSymbols()) {
if (!getCommonSec(relocatable, entry.sym) &&
getSymSectionIndex(entry.sym) == SHN_XINDEX)
@@ -2311,7 +2312,7 @@ void GnuHashTableSection::writeTo(uint8_t *buf) {
buf += 16;
// Write the 2-bit bloom filter.
- const unsigned c = ctx.arg.is64 ? 64 : 32;
+ const unsigned c = ctx.arg.getIs64() ? 64 : 32;
for (const Entry &sym : symbols) {
// When C = 64, we choose a word with bits [6:...] and set 1 to two bits in
// the word using bits [0:5] and [26:31].
@@ -2479,7 +2480,8 @@ size_t PltSection::getSize() const {
bool PltSection::isNeeded() const {
// For -z retpolineplt, .iplt needs the .plt header.
- return !entries.empty() || (ctx.arg.zRetpolineplt && ctx.in.iplt->isNeeded());
+ return !entries.empty() ||
+ (ctx.arg.getZRetpolineplt() && ctx.in.iplt->isNeeded());
}
// Used by ARM to add mapping symbols in the PLT section, which aid
@@ -3657,7 +3659,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
verneeds.emplace_back();
Verneed &vn = verneeds.back();
vn.nameStrTab = ctx.in.dynStrTab->addString(f->soName);
- bool isLibc = ctx.arg.relrGlibc && f->soName.starts_with("libc.so.");
+ bool isLibc = ctx.arg.getRelrGlibc() && f->soName.starts_with("libc.so.");
bool isGlibc2 = false;
for (unsigned i = 0; i != f->verneedInfo.size(); ++i) {
if (f->verneedInfo[i].id == 0)
@@ -4113,7 +4115,7 @@ ThunkSection::ThunkSection(Ctx &ctx, OutputSection *os, uint64_t off)
}
size_t ThunkSection::getSize() const {
- if (roundUpSizeForErrata)
+ if (getRoundUpSizeForErrata())
return alignTo(size, 4096);
return size;
}
@@ -4187,7 +4189,7 @@ bool ThunkSection::assignOffsets() {
// allocated and filled in by the dynamic linker.
PPC64LongBranchTargetSection::PPC64LongBranchTargetSection(Ctx &ctx)
: SyntheticSection(ctx, ".branch_lt",
- ctx.arg.isPic ? SHT_NOBITS : SHT_PROGBITS,
+ ctx.arg.getIsPic() ? SHT_NOBITS : SHT_PROGBITS,
SHF_ALLOC | SHF_WRITE, 8) {}
uint64_t PPC64LongBranchTargetSection::getEntryVA(const Symbol *sym,
@@ -4213,7 +4215,7 @@ void PPC64LongBranchTargetSection::writeTo(uint8_t *buf) {
// If linking non-pic we have the final addresses of the targets and they get
// written to the table directly. For pic the dynamic linker will allocate
// the section and fill it.
- if (ctx.arg.isPic)
+ if (ctx.arg.getIsPic())
return;
for (auto entry : entries) {
@@ -4236,13 +4238,13 @@ bool PPC64LongBranchTargetSection::isNeeded() const {
// only gets set to true once `finalizeSections()` is called after thunk
// creation. Because of this, if we don't create any long-branch thunks we end
// up with an empty .branch_lt section in the binary.
- return !finalized || !entries.empty();
+ return !getFinalized() || !entries.empty();
}
static uint8_t getAbiVersion(Ctx &ctx) {
// MIPS non-PIC executable gets ABI version 1.
if (ctx.arg.emachine == EM_MIPS) {
- if (!ctx.arg.isPic && !ctx.arg.relocatable &&
+ if (!ctx.arg.getIsPic() && !ctx.arg.getRelocatable() &&
(ctx.arg.eflags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC)
return 1;
return 0;
@@ -4276,7 +4278,7 @@ template <typename ELFT> void elf::writeEhdr(Ctx &ctx, uint8_t *buf) {
eHdr->e_phnum = ctx.phdrs.size();
eHdr->e_shentsize = sizeof(typename ELFT::Shdr);
- if (!ctx.arg.relocatable) {
+ if (!ctx.arg.getRelocatable()) {
eHdr->e_phoff = sizeof(typename ELFT::Ehdr);
eHdr->e_phentsize = sizeof(typename ELFT::Phdr);
}
@@ -4299,7 +4301,7 @@ template <typename ELFT> void elf::writePhdrs(Ctx &ctx, uint8_t *buf) {
}
static bool needsInterpSection(Ctx &ctx) {
- return !ctx.arg.relocatable && !ctx.arg.shared &&
+ return !ctx.arg.getRelocatable() && !ctx.arg.getShared() &&
!ctx.arg.dynamicLinker.empty() && ctx.script->needsInterpSection();
}
@@ -4315,8 +4317,8 @@ bool elf::hasMemtag(Ctx &ctx) {
// This restriction could be removed in future by re-using some of the ideas
// that ifuncs use in fully static executables.
bool elf::canHaveMemtagGlobals(Ctx &ctx) {
- return hasMemtag(ctx) &&
- (ctx.arg.relocatable || ctx.arg.shared || needsInterpSection(ctx));
+ return hasMemtag(ctx) && (ctx.arg.getRelocatable() || ctx.arg.getShared() ||
+ needsInterpSection(ctx));
}
constexpr char kMemtagAndroidNoteName[] = "Android";
@@ -4486,7 +4488,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
auto add = [&](SyntheticSection &sec) { ctx.inputSections.push_back(&sec); };
- if (ctx.arg.zSectionHeader)
+ if (ctx.arg.getZSectionHeader())
ctx.in.shStrTab =
std::make_unique<StringTableSection>(ctx, ".shstrtab", false);
@@ -4508,14 +4510,14 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
// .data.rel.ro.bss so that we match in the .data.rel.ro output section.
// This makes sure our relro is contiguous.
bool hasDataRelRo =
- ctx.script->hasSectionsCommand && findSection(ctx, ".data.rel.ro");
+ ctx.script->getHasSectionsCommand() && findSection(ctx, ".data.rel.ro");
ctx.in.bssRelRo = std::make_unique<BssSection>(
ctx, hasDataRelRo ? ".data.rel.ro.bss" : ".bss.rel.ro", 0, 1);
add(*ctx.in.bssRelRo);
ctx.target->initTargetSpecificSections();
- StringRef relaDynName = ctx.arg.isRela ? ".rela.dyn" : ".rel.dyn";
+ StringRef relaDynName = ctx.arg.getIsRela() ? ".rela.dyn" : ".rel.dyn";
const unsigned threadCount = ctx.arg.threadCount;
do {
@@ -4531,7 +4533,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
ctx.in.dynSymTab =
std::make_unique<SymbolTableSection<ELFT>>(ctx, *ctx.in.dynStrTab);
- if (ctx.arg.relocatable)
+ if (ctx.arg.getRelocatable())
break;
ctx.in.dynamic = std::make_unique<DynamicSection<ELFT>>(ctx);
@@ -4554,7 +4556,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
ctx.in.relaDyn = std::make_unique<RelocationSection<ELFT>>(
ctx, relaDynName, /*combreloc=*/true, threadCount);
- if (ctx.hasDynsym) {
+ if (ctx.getHasDynsym()) {
add(*ctx.in.dynSymTab);
ctx.in.verSym = std::make_unique<VersionTableSection>(ctx);
@@ -4573,7 +4575,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
add(*ctx.in.gnuHashTab);
}
- if (ctx.arg.sysvHash) {
+ if (ctx.arg.getSysvHash()) {
ctx.in.hashTab = std::make_unique<HashTableSection>(ctx);
add(*ctx.in.hashTab);
}
@@ -4626,9 +4628,9 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
add(*ctx.in.igotPlt);
// Add .relro_padding if DATA_SEGMENT_RELRO_END is used; otherwise, add the
// section in the absence of PHDRS/SECTIONS commands.
- if (ctx.arg.zRelro &&
- ((!ctx.script->hasPhdrsCommands() && !ctx.script->hasSectionsCommand) ||
- ctx.script->seenRelroEnd)) {
+ if (ctx.arg.getZRelro() && ((!ctx.script->hasPhdrsCommands() &&
+ !ctx.script->getHasSectionsCommand()) ||
+ ctx.script->getSeenRelroEnd())) {
ctx.in.relroPadding = std::make_unique<RelroPaddingSection>(ctx);
add(*ctx.in.relroPadding);
}
@@ -4645,7 +4647,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
// We always need to add rel[a].plt to output if it has entries.
// Even for static linking it can contain R_[*]_IRELATIVE relocations.
ctx.in.relaPlt = std::make_unique<RelocationSection<ELFT>>(
- ctx, ctx.arg.isRela ? ".rela.plt" : ".rel.plt", /*sort=*/false,
+ ctx, ctx.arg.getIsRela() ? ".rela.plt" : ".rel.plt", /*sort=*/false,
/*threadCount=*/1);
add(*ctx.in.relaPlt);
@@ -4677,7 +4679,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
// section to control the executable-ness of the stack area, but that
// is irrelevant these days. Stack area should always be non-executable
// by default. So we emit this section unconditionally.
- if (ctx.arg.relocatable) {
+ if (ctx.arg.getRelocatable()) {
ctx.in.gnuStack = std::make_unique<GnuStackSection>(ctx);
add(*ctx.in.gnuStack);
}
@@ -4694,7 +4696,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
if (ctx.dynDbgOutput) {
ctx.in.dynDbg = std::make_unique<DynamicDebugSection>(ctx);
add(*ctx.in.dynDbg);
- if (!ctx.arg.relocatable) {
+ if (!ctx.arg.getRelocatable()) {
ctx.in.dynDbgNote = std::make_unique<DynamicDebugNote>(ctx);
add(*ctx.in.dynDbgNote);
}
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 85596e1339545..89af2daf75161 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -28,6 +28,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/MC/StringTableBuilder.h"
@@ -105,8 +106,11 @@ class EhFrameHeader final : public SyntheticSection {
// Cached FDE data computed by updateAllocSize, used by
// EhFrameSection::writeTo.
- SmallVector<EhFrameSection::FdeData, 0> fdes;
- bool large = false; // Whether to use sdata8 encoding.
+ llvm::SmallVectorWithFlags<EhFrameSection::FdeData, 0> fdes;
+ bool getLarge() const { return fdes.getFlag(0); }
+ void setLarge(bool Value) {
+ fdes.setFlag(0, Value);
+ } // Whether to use sdata8 encoding.
size_t size = 0;
};
@@ -415,13 +419,19 @@ class StringTableSection final : public SyntheticSection {
unsigned addString(StringRef s, bool hashIt = true);
void writeTo(uint8_t *buf) override;
size_t getSize() const override { return size; }
- bool isDynamic() const { return dynamic; }
+ bool isDynamic() const { return getDynamic(); }
private:
- const bool dynamic;
+ bool getDynamic() const { return strings.getFlag(0); }
llvm::DenseMap<llvm::CachedHashStringRef, unsigned> stringMap;
- SmallVector<StringRef, 0> strings;
+ llvm::SmallVectorWithFlags<StringRef, 0> strings;
+
+public:
+ StringTableSection(const StringTableSection &) = default;
+ StringTableSection(StringTableSection &&) = default;
+ StringTableSection &operator=(const StringTableSection &) = delete;
+ StringTableSection &operator=(StringTableSection &&) = delete;
};
class DynamicReloc {
@@ -1247,10 +1257,14 @@ class ThunkSection final : public SyntheticSection {
// When true, round up reported size of section to 4 KiB. See comment
// in addThunkSection() for more details.
- bool roundUpSizeForErrata = false;
+ bool getRoundUpSizeForErrata() const { return thunks.getFlag(0); }
+ bool setRoundUpSizeForErrata(bool Value) {
+ thunks.setFlag(0, Value);
+ return Value;
+ }
private:
- SmallVector<Thunk *, 0> thunks;
+ llvm::SmallVectorWithFlags<Thunk *, 0> thunks;
size_t size = 0;
};
@@ -1267,12 +1281,13 @@ class PPC64LongBranchTargetSection final : public SyntheticSection {
size_t getSize() const override;
void writeTo(uint8_t *buf) override;
bool isNeeded() const override;
- void finalizeContents() override { finalized = true; }
+ void finalizeContents() override { setFinalized(true); }
private:
- SmallVector<std::pair<const Symbol *, int64_t>, 0> entries;
+ llvm::SmallVectorWithFlags<std::pair<const Symbol *, int64_t>, 0> entries;
llvm::DenseMap<std::pair<const Symbol *, int64_t>, uint32_t> entry_index;
- bool finalized = false;
+ bool getFinalized() const { return entries.getFlag(0); }
+ void setFinalized(bool Value) { entries.setFlag(0, Value); }
};
// See the following link for the Android-specific loader code that operates on
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp
index 89e4dbeed3109..abea5923caac2 100644
--- a/lld/ELF/Target.cpp
+++ b/lld/ELF/Target.cpp
@@ -152,7 +152,7 @@ RelExpr TargetInfo::adjustGotPcExpr(RelType type, int64_t addend,
static void relocateImpl(const TargetInfo &target, InputSectionBase &sec,
uint64_t secAddr, uint8_t *buf) {
auto &ctx = target.ctx;
- const unsigned bits = ctx.arg.is64 ? 64 : 32;
+ const unsigned bits = ctx.arg.getIs64() ? 64 : 32;
for (const Relocation &rel : sec.relocs()) {
uint8_t *loc = buf + rel.offset;
const uint64_t val = SignExtend64(
@@ -177,5 +177,5 @@ uint64_t TargetInfo::getImageBase() const {
// Use --image-base if set. Fall back to the target default if not.
if (ctx.arg.imageBase)
return *ctx.arg.imageBase;
- return ctx.arg.isPic ? 0 : defaultImageBase;
+ return ctx.arg.getIsPic() ? 0 : defaultImageBase;
}
diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 88d66086a9dcf..020ff0e2d48f1 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -426,7 +426,7 @@ class HexagonThunk : public Thunk {
alignment = 4;
}
uint32_t relOffset;
- uint32_t size() override { return ctx.arg.isPic ? 12 : 8; }
+ uint32_t size() override { return ctx.arg.getIsPic() ? 12 : 8; }
void writeTo(uint8_t *buf) override;
void addSymbols(ThunkSection &isec) override;
};
@@ -485,7 +485,7 @@ class PPC32LongThunk final : public Thunk {
public:
PPC32LongThunk(Ctx &ctx, Symbol &dest, int64_t addend)
: Thunk(ctx, dest, addend) {}
- uint32_t size() override { return ctx.arg.isPic ? 32 : 16; }
+ uint32_t size() override { return ctx.arg.getIsPic() ? 32 : 16; }
void writeTo(uint8_t *buf) override;
void addSymbols(ThunkSection &isec) override;
};
@@ -1313,7 +1313,7 @@ InputSection *MicroMipsR6Thunk::getTargetInputSection() const {
void elf::writePPC32PltCallStub(Ctx &ctx, uint8_t *buf, uint64_t p,
uint64_t gotPltVA, const InputFile *file,
std::optional<int64_t> addend) {
- if (!ctx.arg.isPic) {
+ if (!ctx.arg.getIsPic()) {
write32(ctx, buf + 0, 0x3d600000 | (gotPltVA + 0x8000) >> 16); // lis r11,ha
write32(ctx, buf + 4, 0x816b0000 | (uint16_t)gotPltVA); // lwz r11,l(r11)
write32(ctx, buf + 8, 0x7d6903a6); // mtctr r11
@@ -1373,7 +1373,7 @@ void PPC32PltCallStub::addSymbols(ThunkSection &isec) {
std::string buf;
raw_string_ostream os(buf);
os << format_hex_no_prefix(addend, 8);
- if (!ctx.arg.isPic)
+ if (!ctx.arg.getIsPic())
os << ".plt_call32.";
else if (addend >= 0x8000)
os << ".got2.plt_pic32.";
@@ -1385,7 +1385,7 @@ void PPC32PltCallStub::addSymbols(ThunkSection &isec) {
bool PPC32PltCallStub::isCompatibleWith(const InputSection &isec,
const Relocation &rel) const {
- return !ctx.arg.isPic || (isec.file == file && rel.addend == addend);
+ return !ctx.arg.getIsPic() || (isec.file == file && rel.addend == addend);
}
void PPC32LongThunk::addSymbols(ThunkSection &isec) {
@@ -1397,7 +1397,7 @@ void PPC32LongThunk::writeTo(uint8_t *buf) {
auto ha = [](uint32_t v) -> uint16_t { return (v + 0x8000) >> 16; };
auto lo = [](uint32_t v) -> uint16_t { return v; };
uint32_t d = destination.getVA(ctx, addend);
- if (ctx.arg.isPic) {
+ if (ctx.arg.getIsPic()) {
uint32_t off = d - (getThunkTargetSym()->getVA(ctx) + 8);
write32(ctx, buf + 0, 0x7c0802a6); // mflr r12,0
write32(ctx, buf + 4, 0x429f0005); // bcl r20,r31,.+4
@@ -1507,7 +1507,7 @@ void PPC64R12SetupStub::writeTo(uint8_t *buf) {
"R12 setup stub offset");
int nextInstOffset;
- if (ctx.arg.power10Stubs) {
+ if (ctx.arg.getPower10Stubs()) {
const uint64_t imm = (((offset >> 16) & 0x3ffff) << 32) | (offset & 0xffff);
// pld 12, func at plt@pcrel or paddi r12, 0, func at pcrel
writePrefixedInst(ctx, buf,
@@ -1568,7 +1568,7 @@ void HexagonThunk::writeTo(uint8_t *buf) {
uint64_t s = getHexagonThunkDestVA(ctx, destination, addend);
uint64_t p = getThunkTargetSym()->getVA(ctx);
- if (ctx.arg.isPic) {
+ if (ctx.arg.getIsPic()) {
write32(ctx, buf + 0, 0x00004000); // { immext(#0)
ctx.target->relocateNoSym(buf, R_HEX_B32_PCREL_X, s - p);
write32(ctx, buf + 4, 0x6a49c00e); // r14 = add(pc,##0) }
@@ -1606,7 +1606,7 @@ static std::unique_ptr<Thunk> addThunkAArch64(Ctx &ctx, const InputSection &sec,
bool mayNeedLandingPad =
(ctx.arg.andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) &&
!isAArch64BTILandingPad(ctx, s, a);
- if (ctx.arg.picThunk)
+ if (ctx.arg.getPicThunk())
return std::make_unique<AArch64ADRPThunk>(ctx, s, a, mayNeedLandingPad);
if (sec.getParent()->flags & SHF_AARCH64_PURECODE)
return std::make_unique<AArch64ABSXOLongThunk>(ctx, s, a,
@@ -1631,7 +1631,7 @@ static std::unique_ptr<Thunk> addThunkArmv4(Ctx &ctx, RelType reloc, Symbol &s,
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
- if (ctx.arg.picThunk) {
+ if (ctx.arg.getPicThunk()) {
if (thumb_target)
return std::make_unique<ARMV4PILongBXThunk>(ctx, s, a);
return std::make_unique<ARMV4PILongThunk>(ctx, s, a);
@@ -1640,7 +1640,7 @@ static std::unique_ptr<Thunk> addThunkArmv4(Ctx &ctx, RelType reloc, Symbol &s,
return std::make_unique<ARMV4ABSLongBXThunk>(ctx, s, a);
return std::make_unique<ARMV5LongLdrPcThunk>(ctx, s, a);
case R_ARM_THM_CALL:
- if (ctx.arg.picThunk) {
+ if (ctx.arg.getPicThunk()) {
if (thumb_target)
return std::make_unique<ThumbV4PILongThunk>(ctx, s, a);
return std::make_unique<ThumbV4PILongBXThunk>(ctx, s, a);
@@ -1667,7 +1667,7 @@ static std::unique_ptr<Thunk> addThunkArmv5v6(Ctx &ctx, RelType reloc,
case R_ARM_JUMP24:
case R_ARM_CALL:
case R_ARM_THM_CALL:
- if (ctx.arg.picThunk)
+ if (ctx.arg.getPicThunk())
return std::make_unique<ARMV4PILongBXThunk>(ctx, s, a);
return std::make_unique<ARMV5LongLdrPcThunk>(ctx, s, a);
}
@@ -1688,7 +1688,7 @@ static std::unique_ptr<Thunk> addThunkV6M(Ctx &ctx, const InputSection &isec,
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- if (ctx.arg.isPic) {
+ if (ctx.arg.getIsPic()) {
if (!isPureCode)
return std::make_unique<ThumbV6MPILongThunk>(ctx, s, a);
@@ -1740,13 +1740,13 @@ static std::unique_ptr<Thunk> addThunkArm(Ctx &ctx, const InputSection &isec,
case R_ARM_PLT32:
case R_ARM_JUMP24:
case R_ARM_CALL:
- if (ctx.arg.picThunk)
+ if (ctx.arg.getPicThunk())
return std::make_unique<ARMV7PILongThunk>(ctx, s, a);
return std::make_unique<ARMV7ABSLongThunk>(ctx, s, a);
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
case R_ARM_THM_CALL:
- if (ctx.arg.picThunk)
+ if (ctx.arg.getPicThunk())
return std::make_unique<ThumbV7PILongThunk>(ctx, s, a);
return std::make_unique<ThumbV7ABSLongThunk>(ctx, s, a);
}
@@ -1827,7 +1827,7 @@ static std::unique_ptr<Thunk> addThunkPPC64(Ctx &ctx, RelType type, Symbol &s,
if (type == R_PPC64_REL24_NOTOC)
return std::make_unique<PPC64R12SetupStub>(ctx, s, /*gotPlt=*/false);
- if (ctx.arg.picThunk)
+ if (ctx.arg.getPicThunk())
return std::make_unique<PPC64PILongBranchThunk>(ctx, s, a);
return std::make_unique<PPC64PDLongBranchThunk>(ctx, s, a);
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index ae803184918d8..049687f089de6 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -221,7 +221,7 @@ void elf::addReservedSymbols(Ctx &ctx) {
STV_HIDDEN);
// If linker script do layout we do not need to create any standard symbols.
- if (ctx.script->hasSectionsCommand)
+ if (ctx.script->getHasSectionsCommand())
return;
auto add = [&](StringRef s, int64_t pos) {
@@ -312,7 +312,7 @@ template <class ELFT> void Writer<ELFT>::run() {
for (OutputSection *sec : ctx.outputSections)
sec->maybeCompress<ELFT>(ctx);
- if (ctx.script->hasSectionsCommand)
+ if (ctx.script->getHasSectionsCommand())
ctx.script->allocateHeaders(ctx.phdrs);
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
@@ -320,7 +320,7 @@ template <class ELFT> void Writer<ELFT>::run() {
// we know the size of the sections.
removeEmptyPTLoad(ctx, ctx.phdrs);
- if (!ctx.arg.oFormatBinary)
+ if (!ctx.arg.getOFormatBinary())
assignFileOffsets();
else
assignFileOffsetsBinary();
@@ -333,10 +333,10 @@ template <class ELFT> void Writer<ELFT>::run() {
writeMapAndCref(ctx);
// Handle --print-memory-usage option.
- if (ctx.arg.printMemoryUsage)
+ if (ctx.arg.getPrintMemoryUsage())
ctx.script->printMemoryUsage(ctx.e.outs());
- if (ctx.arg.checkSections)
+ if (ctx.arg.getCheckSections())
checkSections();
// It does not make sense try to open the file if we have error already.
@@ -350,7 +350,7 @@ template <class ELFT> void Writer<ELFT>::run() {
if (errCount(ctx))
return;
- if (!ctx.arg.oFormatBinary) {
+ if (!ctx.arg.getOFormatBinary()) {
if (ctx.arg.zSeparate != SeparateSegmentKind::None)
writeTrapInstr();
writeHeader();
@@ -370,7 +370,7 @@ template <class ELFT> void Writer<ELFT>::run() {
// Otherwise, with -o -, write to lld::outs() (the stdoutOS argument of
// link()) instead of committing the buffer, which would write to the
// process's stdout.
- if (ctx.inDynDbgLink)
+ if (ctx.getInDynDbgLink())
ctx.dynDbgOutput = std::move(buffer);
else if (ctx.arg.outputFile == "-") {
ctx.e.outs() << StringRef(
@@ -388,7 +388,7 @@ template <class ELFT> void Writer<ELFT>::run() {
}
static bool retainKeepsInSymtab(Ctx &ctx, const Symbol &sym) {
- if (sym.hasFlag(USED) && ctx.arg.copyRelocs)
+ if (sym.hasFlag(USED) && ctx.arg.getCopyRelocs())
return true;
return ctx.arg.retainSymbols->contains(sym.getName());
}
@@ -399,7 +399,7 @@ static bool shouldKeepInSymtab(Ctx &ctx, const Defined &sym) {
// If --emit-reloc or -r is given, preserve symbols referenced by relocations
// from live sections.
- if (sym.hasFlag(USED) && ctx.arg.copyRelocs)
+ if (sym.hasFlag(USED) && ctx.arg.getCopyRelocs())
return true;
// Exclude local symbols pointing to .ARM.exidx sections.
@@ -477,7 +477,7 @@ static void demoteAndCopyLocalSymbols(Ctx &ctx) {
// not attributed to another file's STT_FILE (matching GNU ld).
// --discard-all discards STT_FILE symbols.
auto &syms = symsVec[i];
- if (ctx.arg.relocatable && ctx.arg.discard != DiscardPolicy::All &&
+ if (ctx.arg.getRelocatable() && ctx.arg.discard != DiscardPolicy::All &&
!syms.empty() &&
llvm::none_of(syms, [](Symbol *s) { return s->isFile(); })) {
InputFile *file = ctx.objectFiles[i];
@@ -543,7 +543,7 @@ static bool isRelRoDataSection(Ctx &ctx, StringRef secName) {
return true;
// If -z keep-data-section-prefix is specified, additionally allow
// '.data.rel.ro.hot' and '.data.rel.ro.unlikely'.
- if (ctx.arg.zKeepDataSectionPrefix)
+ if (ctx.arg.getZKeepDataSectionPrefix())
return secName == ".hot" || secName == ".unlikely";
return false;
}
@@ -555,9 +555,9 @@ static bool isRelRoDataSection(Ctx &ctx, StringRef secName) {
// This function returns true if a section needs to be put into a
// PT_GNU_RELRO segment.
static bool isRelroSection(Ctx &ctx, const OutputSection *sec) {
- if (!ctx.arg.zRelro)
+ if (!ctx.arg.getZRelro())
return false;
- if (sec->relro)
+ if (sec->getRelro())
return true;
uint64_t flags = sec->flags;
@@ -607,7 +607,7 @@ static bool isRelroSection(Ctx &ctx, const OutputSection *sec) {
// However, if "-z now" is given, the lazy symbol resolution is
// disabled, which enables us to put it into RELRO.
if (sec == ctx.in.gotPlt->getParent())
- return ctx.arg.zNow;
+ return ctx.arg.getZNow();
if (ctx.in.relroPadding && sec == ctx.in.relroPadding->getParent())
return true;
@@ -694,9 +694,9 @@ unsigned elf::getSectionRank(Ctx &ctx, OutputSection &osec) {
// pressure for absolute relocations referencing small data from -fno-pic
// relocatable files.
if (isLarge)
- rank |= ctx.arg.zLrodataAfterBss ? RF_LARGE_ALT : 0;
+ rank |= ctx.arg.getZLrodataAfterBss() ? RF_LARGE_ALT : 0;
else
- rank |= ctx.arg.zLrodataAfterBss ? 0 : RF_LARGE;
+ rank |= ctx.arg.getZLrodataAfterBss() ? 0 : RF_LARGE;
if (osec.name == ".interp")
rank |= 1;
@@ -727,7 +727,7 @@ unsigned elf::getSectionRank(Ctx &ctx, OutputSection &osec) {
if (!(osec.flags & SHF_TLS))
rank |= RF_NOT_TLS;
if (isRelroSection(ctx, &osec))
- osec.relro = true;
+ osec.setRelro(true);
else
rank |= RF_NOT_RELRO;
// Place .ldata and .lbss after .bss. Making .bss closer to .text
@@ -735,7 +735,7 @@ unsigned elf::getSectionRank(Ctx &ctx, OutputSection &osec) {
// For -z lrodata-after-bss, place .lbss/.lrodata/.ldata after .bss.
// .bss/.lbss being adjacent reuses the NOBITS size optimization.
if (isLarge) {
- rank |= ctx.arg.zLrodataAfterBss
+ rank |= ctx.arg.getZLrodataAfterBss()
? (osec.type == SHT_NOBITS ? 1 : RF_LARGE_ALT)
: RF_LARGE;
}
@@ -809,13 +809,14 @@ void PhdrEntry::add(OutputSection *sec) {
// processed by the libc runtime. Other executables or DSOs use dynamic tags
// instead.
template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
- if (ctx.arg.isPic)
+ if (ctx.arg.getIsPic())
return;
// __rela_iplt_{start,end} are initially defined relative to dummy section 0.
// We'll override ctx.out.elfHeader with relaDyn later when we are sure that
// .rela.dyn will be present in the output.
- std::string name = ctx.arg.isRela ? "__rela_iplt_start" : "__rel_iplt_start";
+ std::string name =
+ ctx.arg.getIsRela() ? "__rela_iplt_start" : "__rel_iplt_start";
ctx.sym.relaIpltStart =
addOptionalRegular(ctx, name, ctx.out.elfHeader.get(), 0, STV_HIDDEN);
name.replace(name.size() - 5, 5, "end");
@@ -932,7 +933,7 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
// countLeadingZeros.
static int getRankProximity(OutputSection *a, SectionCommand *b) {
auto *osd = dyn_cast<OutputDesc>(b);
- return (osd && osd->osec.hasInputSections)
+ return (osd && osd->osec.getHasInputSections())
? llvm::countl_zero(a->sortRank ^ osd->osec.sortRank)
: -1;
}
@@ -1002,7 +1003,7 @@ findOrphanPos(Ctx &ctx, SmallVectorImpl<SectionCommand *>::iterator b,
auto isOutputSecWithInputSections = [](SectionCommand *cmd) {
auto *osd = dyn_cast<OutputDesc>(cmd);
- return osd && osd->osec.hasInputSections;
+ return osd && osd->osec.getHasInputSections();
};
// Then, scan backward or forward through the script for a suitable insertion
@@ -1087,16 +1088,18 @@ static void maybeShuffle(Ctx &ctx,
// that don't appear in the order file.
static DenseMap<const InputSectionBase *, int> buildSectionOrder(Ctx &ctx) {
DenseMap<const InputSectionBase *, int> sectionOrder;
- if (ctx.arg.bpStartupFunctionSort || ctx.arg.bpFunctionOrderForCompression ||
- ctx.arg.bpDataOrderForCompression ||
+ if (ctx.arg.getBpStartupFunctionSort() ||
+ ctx.arg.getBpFunctionOrderForCompression() ||
+ ctx.arg.getBpDataOrderForCompression() ||
!ctx.arg.bpCompressionSortSpecs.empty()) {
TimeTraceScope timeScope("Balanced Partitioning Section Orderer");
sectionOrder = runBalancedPartitioning(
- ctx, ctx.arg.bpStartupFunctionSort ? ctx.arg.irpgoProfilePath : "",
- ctx.arg.bpCompressionSortSpecs, ctx.arg.bpFunctionOrderForCompression,
- ctx.arg.bpDataOrderForCompression,
- ctx.arg.bpCompressionSortStartupFunctions,
- ctx.arg.bpVerboseSectionOrderer);
+ ctx, ctx.arg.getBpStartupFunctionSort() ? ctx.arg.irpgoProfilePath : "",
+ ctx.arg.bpCompressionSortSpecs,
+ ctx.arg.getBpFunctionOrderForCompression(),
+ ctx.arg.getBpDataOrderForCompression(),
+ ctx.arg.getBpCompressionSortStartupFunctions(),
+ ctx.arg.getBpVerboseSectionOrderer());
} else if (!ctx.arg.callGraphProfile.empty()) {
sectionOrder = computeCallGraphProfileOrder(ctx);
}
@@ -1246,7 +1249,7 @@ static void sortSection(Ctx &ctx, OutputSection &osec,
if (auto *isd = dyn_cast<InputSectionDescription>(b))
sortISDBySectionOrder(ctx, isd, order, osec.flags & SHF_EXECINSTR);
- if (ctx.script->hasSectionsCommand)
+ if (ctx.script->getHasSectionsCommand())
return;
if (name == ".init_array" || name == ".fini_array") {
@@ -1263,8 +1266,8 @@ static void sortSection(Ctx &ctx, OutputSection &osec,
auto *isd = cast<InputSectionDescription>(osec.commands[0]);
llvm::stable_sort(isd->sections,
[](const InputSection *a, const InputSection *b) -> bool {
- return a->file->ppc64SmallCodeModelTocRelocs &&
- !b->file->ppc64SmallCodeModelTocRelocs;
+ return a->file->getPpc64SmallCodeModelTocRelocs() &&
+ !b->file->getPpc64SmallCodeModelTocRelocs();
});
}
}
@@ -1285,7 +1288,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
// Don't sort if using -r. It is not necessary and we want to preserve the
// relative order for SHF_LINK_ORDER sections.
- if (ctx.arg.relocatable) {
+ if (ctx.arg.getRelocatable()) {
ctx.script->adjustOutputSections();
return;
}
@@ -1295,7 +1298,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
for (SectionCommand *cmd : ctx.script->sectionCommands)
if (auto *osd = dyn_cast<OutputDesc>(cmd))
osd->osec.sortRank = getSectionRank(ctx, osd->osec);
- if (!ctx.script->hasSectionsCommand) {
+ if (!ctx.script->getHasSectionsCommand()) {
// OutputDescs are mostly contiguous, but may be interleaved with
// SymbolAssignments in the presence of INSERT commands.
auto mid = std::stable_partition(
@@ -1311,7 +1314,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
ctx.script->processInsertCommands();
ctx.script->adjustOutputSections();
- if (ctx.script->hasSectionsCommand)
+ if (ctx.script->getHasSectionsCommand())
sortOrphanSections();
ctx.script->adjustSectionsAfterSorting();
@@ -1421,7 +1424,7 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
// The ARM.exidx section use SHF_LINK_ORDER, but we have consolidated
// this processing inside the ARMExidxsyntheticsection::finalizeContents().
- if (!ctx.arg.relocatable && ctx.arg.emachine == EM_ARM &&
+ if (!ctx.arg.getRelocatable() && ctx.arg.emachine == EM_ARM &&
sec->type == SHT_ARM_EXIDX)
continue;
@@ -1509,7 +1512,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
// After the first assignAddresses, only the loop below may change layout.
if (ctx.arg.randomizeSectionPadding)
randomizeSectionPadding(ctx);
- if (ctx.arg.branchToBranch)
+ if (ctx.arg.getBranchToBranch())
ctx.target->relaxCFIJumpTables();
ctx.script->assignAddresses();
@@ -1527,7 +1530,7 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
// Iterate until a fixed point is reached, skipping relocatable links since
// the final addresses are unavailable.
uint32_t pass = 0, assignPasses = 0;
- while (!ctx.arg.relocatable) {
+ while (!ctx.arg.getRelocatable()) {
bool changed = ctx.target->needsThunks
? tc.createThunks(pass, ctx.outputSections)
: ctx.target->relaxOnce(pass);
@@ -1628,16 +1631,17 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
if (errCount(ctx))
break;
}
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
ctx.target->finalizeRelax(pass);
- if (ctx.arg.relocatable)
+ if (ctx.arg.getRelocatable())
for (OutputSection *sec : ctx.outputSections)
sec->addr = 0;
- uint64_t imageBase = ctx.script->hasSectionsCommand || ctx.arg.relocatable
- ? 0
- : ctx.target->getImageBase();
+ uint64_t imageBase =
+ ctx.script->getHasSectionsCommand() || ctx.arg.getRelocatable()
+ ? 0
+ : ctx.target->getImageBase();
for (SectionCommand *cmd : ctx.script->sectionCommands) {
auto *osd = dyn_cast<OutputDesc>(cmd);
if (!osd)
@@ -1715,7 +1719,7 @@ static void fixSymbolsAfterShrinking(Ctx &ctx) {
// relaxation pass does that. It is only enabled when --optimize-bb-jumps
// option is used.
template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
- assert(ctx.arg.optimizeBBJumps);
+ assert(ctx.arg.getOptimizeBBJumps());
SmallVector<InputSection *, 0> storage;
ctx.script->assignAddresses();
@@ -1755,7 +1759,7 @@ template <class ELFT> void Writer<ELFT>::optimizeBasicBlockJumps() {
// Sections that finalizeAddressDependentContent may add to.
static bool mayGrowLate(Ctx &ctx, SyntheticSection *sec) {
// relaxOnce may add GOT entries that need relative relocations.
- if (ctx.arg.isPic && ctx.in.got && ctx.in.got->hasDeferredEntries &&
+ if (ctx.arg.getIsPic() && ctx.in.got && ctx.in.got->hasDeferredEntries &&
sec == (ctx.in.relrDyn
? static_cast<SyntheticSection *>(ctx.in.relrDyn.get())
: ctx.in.relaDyn.get()))
@@ -1766,7 +1770,7 @@ static bool mayGrowLate(Ctx &ctx, SyntheticSection *sec) {
if (ctx.in.relrAuthDyn && ctx.in.relrAuthDyn->isNeeded())
return true;
// PPC64PILongBranchThunk adds a relative relocation for its .branch_lt entry.
- return ctx.in.ppc64LongBranchTarget && ctx.arg.picThunk;
+ return ctx.in.ppc64LongBranchTarget && ctx.arg.getPicThunk();
}
// In order to allow users to manipulate linker-synthesized sections,
@@ -1823,7 +1827,7 @@ static void removeUnusedSyntheticSections(Ctx &ctx) {
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::finalizeSections() {
- if (!ctx.arg.relocatable) {
+ if (!ctx.arg.getRelocatable()) {
ctx.out.preinitArray = findSection(ctx, ".preinit_array");
ctx.out.initArray = findSection(ctx, ".init_array");
ctx.out.finiArray = findSection(ctx, ".fini_array");
@@ -1855,14 +1859,14 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// value/section does not matter but it has to be relative, so set its
// st_shndx arbitrarily to 1 (ctx.out.elfHeader).
if (ctx.arg.emachine == EM_RISCV) {
- if (!ctx.arg.shared) {
+ if (!ctx.arg.getShared()) {
OutputSection *sec = findSection(ctx, ".sdata");
addOptionalRegular(ctx, "__global_pointer$",
sec ? sec : ctx.out.elfHeader.get(), 0x800,
STV_DEFAULT);
// Set riscvGlobalPointer to be used by the optional global pointer
// relaxation.
- if (ctx.arg.relaxGP) {
+ if (ctx.arg.getRelaxGP()) {
Symbol *s = ctx.symtab->find("__global_pointer$");
if (s && s->isDefined())
ctx.sym.riscvGlobalPointer = cast<Defined>(s);
@@ -1911,14 +1915,14 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
demoteAndCopyLocalSymbols(ctx);
- if (ctx.arg.copyRelocs)
+ if (ctx.arg.getCopyRelocs())
addSectionSymbols();
// Change values of linker-script-defined symbols from placeholders (assigned
// by declareSymbols) to actual definitions.
ctx.script->processSymbolAssignments();
- if (!ctx.arg.relocatable) {
+ if (!ctx.arg.getRelocatable()) {
llvm::TimeTraceScope timeScope("Scan relocations");
// Scan relocations. This must be done after every symbol is declared so
// that we can correctly decide if a dynamic relocation is needed. This is
@@ -1929,7 +1933,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Process symbols referenced by the embedded unoptimized part of dynamic
// debugging. Report references to undefined symbols and ensure that
// references to shared symbols have PLT/GOT entries as appropriate.
- if (ctx.hasDynDbg) {
+ if (ctx.getHasDynDbg()) {
InputSection *unknownSec = make<InputSection>(
ctx.internalFile, dynDbgSecName, 0, 0, 0, 0, ArrayRef<uint8_t>());
for (Symbol *sym : ctx.symtab->getSymbols()) {
@@ -2018,7 +2022,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
for (Symbol *sym : ctx.symtab->getSymbols()) {
if (!sym->isUsedInRegularObj || !includeInSymtab(ctx, *sym))
continue;
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
sym->binding = sym->computeBinding(ctx);
if (ctx.in.symTab &&
(!ctx.arg.retainSymbols || retainKeepsInSymtab(ctx, *sym)))
@@ -2033,7 +2037,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
addVerneed(ctx, *sym);
}
}
- if (ctx.in.symTab && !ctx.arg.relocatable)
+ if (ctx.in.symTab && !ctx.arg.getRelocatable())
ctx.in.symTab->maybeAddSttFile();
}
@@ -2076,7 +2080,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Binary and relocatable output does not have PHDRS.
// The headers have to be created before finalize as that can influence the
// image base and the dynamic section on mips includes the image base.
- if (!ctx.arg.relocatable && !ctx.arg.oFormatBinary) {
+ if (!ctx.arg.getRelocatable() && !ctx.arg.getOFormatBinary()) {
ctx.phdrs = ctx.script->hasPhdrsCommands() ? ctx.script->createPhdrs()
: createPhdrs();
if (ctx.arg.emachine == EM_ARM) {
@@ -2142,7 +2146,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
finalizeSynthetic(ctx, ctx.in.dynamic.get());
}
- if (!ctx.script->hasSectionsCommand && !ctx.arg.relocatable)
+ if (!ctx.script->getHasSectionsCommand() && !ctx.arg.getRelocatable())
fixSectionAlignments();
// This is used to:
@@ -2189,7 +2193,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// Relaxation to delete inter-basic block jumps created by basic block
// sections. Run after ctx.in.symTab is finalized as optimizeBasicBlockJumps
// can relax jump instructions based on symbol offset.
- if (ctx.arg.optimizeBBJumps)
+ if (ctx.arg.getOptimizeBBJumps())
optimizeBasicBlockJumps();
// Fill other section headers. The dynamic table is finalized
@@ -2200,7 +2204,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
ctx.script->checkFinalScriptConditions();
- if (ctx.arg.emachine == EM_ARM && !ctx.arg.isLE && ctx.arg.armBe8) {
+ if (ctx.arg.emachine == EM_ARM && !ctx.arg.getIsLE() && ctx.arg.getArmBe8()) {
addArmInputSectionMappingSymbols(ctx);
sortArmMappingSymbols(ctx);
}
@@ -2268,7 +2272,7 @@ template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
Defined *startSym = addOptionalRegular(ctx, start, os, 0);
Defined *stopSym = addOptionalRegular(ctx, end, os, -1);
if (startSym || stopSym)
- os->usedInExpression = true;
+ os->setUsedInExpression(true);
} else {
addOptionalRegular(ctx, start, ctx.out.elfHeader.get(), 0);
addOptionalRegular(ctx, end, ctx.out.elfHeader.get(), 0);
@@ -2301,7 +2305,7 @@ void Writer<ELFT>::addStartStopSymbols(OutputSection &osec) {
Defined *stopSym = addOptionalRegular(ctx, ss.save("__stop_" + s), &osec, -1,
ctx.arg.zStartStopVisibility);
if (startSym || stopSym)
- osec.usedInExpression = true;
+ osec.setUsedInExpression(true);
}
static bool needsPtLoad(OutputSection *sec) {
@@ -2318,7 +2322,7 @@ static bool needsPtLoad(OutputSection *sec) {
// Adjust phdr flags according to certain options.
static uint64_t computeFlags(Ctx &ctx, uint64_t flags) {
- if (ctx.arg.omagic)
+ if (ctx.arg.getOmagic())
return PF_R | PF_W | PF_X;
if (ctx.arg.executeOnly && (flags & PF_X))
return flags & ~PF_R;
@@ -2341,7 +2345,7 @@ SmallVector<std::unique_ptr<PhdrEntry>, 0> Writer<ELFT>::createPhdrs() {
// nmagic or omagic output does not have PT_PHDR, PT_INTERP, or the readonly
// PT_LOAD.
- if (!ctx.arg.nmagic && !ctx.arg.omagic) {
+ if (!ctx.arg.nmagic && !ctx.arg.getOmagic()) {
// The first phdr entry is PT_PHDR which describes the program header
// itself.
addHdr(PT_PHDR, PF_R)->add(ctx.out.programHeaders.get());
@@ -2402,11 +2406,11 @@ SmallVector<std::unique_ptr<PhdrEntry>, 0> Writer<ELFT>::createPhdrs() {
uint64_t incompatible = flags ^ newFlags;
if (!(newFlags & PF_W)) {
// When --no-rosegment is specified, RO and RX sections are compatible.
- if (ctx.arg.singleRoRx)
+ if (ctx.arg.getSingleRoRx())
incompatible &= ~PF_X;
// When --no-xosegment is specified (the default), XO and RX sections are
// compatible.
- if (ctx.arg.singleXoRx)
+ if (ctx.arg.getSingleXoRx())
incompatible &= ~PF_R;
}
if (incompatible)
@@ -2417,7 +2421,7 @@ SmallVector<std::unique_ptr<PhdrEntry>, 0> Writer<ELFT>::createPhdrs() {
if (load && !relroEnds.contains(sec) &&
sec->memRegion == load->firstSec->memRegion &&
(sameLMARegion || load->lastSec == ctx.out.programHeaders.get()) &&
- (ctx.script->hasSectionsCommand || sec->type == SHT_NOBITS ||
+ (ctx.script->getHasSectionsCommand() || sec->type == SHT_NOBITS ||
load->lastSec->type != SHT_NOBITS)) {
load->p_flags |= newFlags;
} else {
@@ -2481,14 +2485,14 @@ SmallVector<std::unique_ptr<PhdrEntry>, 0> Writer<ELFT>::createPhdrs() {
// PT_OPENBSD_NOBTCFI is an OpenBSD-specific header to mark that the
// executable is expected to violate branch-target CFI checks.
- if (ctx.arg.zNoBtCfi)
+ if (ctx.arg.getZNoBtCfi())
addHdr(PT_OPENBSD_NOBTCFI, PF_X);
// PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable
// is expected to perform W^X violations, such as calling mprotect(2) or
// mmap(2) with PROT_WRITE | PROT_EXEC, which is prohibited by default on
// OpenBSD.
- if (ctx.arg.zWxneeded)
+ if (ctx.arg.getZWxneeded())
addHdr(PT_OPENBSD_WXNEEDED, PF_X);
if (OutputSection *cmd = findSection(ctx, ".note.gnu.property"))
@@ -2763,7 +2767,7 @@ static void checkOverlap(Ctx &ctx, StringRef name,
// If both sections are in OVERLAY we allow the overlapping of virtual
// addresses, because it is what OVERLAY was designed for.
- if (isVirtualAddr && a.sec->inOverlay && b.sec->inOverlay)
+ if (isVirtualAddr && a.sec->getInOverlay() && b.sec->getInOverlay())
continue;
Err(ctx) << "section " << a.sec->name << " " << name
@@ -2797,14 +2801,14 @@ template <class ELFT> void Writer<ELFT>::checkSections() {
std::vector<SectionOffset> fileOffs;
for (OutputSection *sec : ctx.outputSections)
if (sec->size > 0 && sec->type != SHT_NOBITS &&
- (!ctx.arg.oFormatBinary || (sec->flags & SHF_ALLOC)))
+ (!ctx.arg.getOFormatBinary() || (sec->flags & SHF_ALLOC)))
fileOffs.push_back({sec, sec->offset});
checkOverlap(ctx, "file", fileOffs, false);
// When linking with -r there is no need to check for overlapping virtual/load
// addresses since those addresses will only be assigned when the final
// executable/shared object is created.
- if (ctx.arg.relocatable)
+ if (ctx.arg.getRelocatable())
return;
// Checking for overlapping virtual and load addresses only needs to take
@@ -2859,9 +2863,9 @@ static uint64_t getEntryAddr(Ctx &ctx) {
}
static uint16_t getELFType(Ctx &ctx) {
- if (ctx.arg.isPic)
+ if (ctx.arg.getIsPic())
return ET_DYN;
- if (ctx.arg.relocatable)
+ if (ctx.arg.getRelocatable())
return ET_REL;
return ET_EXEC;
}
@@ -2909,7 +2913,7 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
// Open a result file.
template <class ELFT> void Writer<ELFT>::openFile() {
- uint64_t maxSize = ctx.arg.is64 ? INT64_MAX : UINT32_MAX;
+ uint64_t maxSize = ctx.arg.getIs64() ? INT64_MAX : UINT32_MAX;
if (fileSize != size_t(fileSize) || maxSize < fileSize) {
std::string msg;
raw_string_ostream s(msg);
@@ -2923,7 +2927,7 @@ template <class ELFT> void Writer<ELFT>::openFile() {
unlinkAsync(ctx.arg.outputFile);
unsigned flags = 0;
- if (!ctx.arg.relocatable)
+ if (!ctx.arg.getRelocatable())
flags |= FileOutputBuffer::F_executable;
if (ctx.arg.mmapOutputFile)
flags |= FileOutputBuffer::F_mmap;
@@ -3016,7 +3020,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
}
// Finally, check that all dynamic relocation addends were written correctly.
- if (ctx.arg.checkDynamicRelocs && ctx.arg.writeAddends) {
+ if (ctx.arg.getCheckDynamicRelocs() && ctx.arg.writeAddends) {
for (OutputSection *sec : ctx.outputSections)
if (isStaticRelSecType(sec->type))
sec->checkDynRelAddends(ctx);
diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index a939d7789a758..2f482e32b95ad 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/BinaryFormat/MachO.h"
@@ -150,7 +151,10 @@ struct Configuration {
bool stripSwiftForceLoad = false;
bool warnDylibInstallName = false;
bool ignoreOptimizationHints = false;
- bool forceExactCpuSubtypeMatch = false;
+ bool getForceExactCpuSubtypeMatch() const { return passPlugins.getFlag(0); }
+ void setForceExactCpuSubtypeMatch(bool Value) {
+ passPlugins.setFlag(0, Value);
+ }
uint32_t headerPad;
uint32_t dylibCompatibilityVersion = 0;
uint32_t dylibCurrentVersion = 0;
@@ -186,30 +190,35 @@ struct Configuration {
bool demangle = false;
bool deadStrip = false;
bool interposable = false;
- bool errorForArchMismatch = false;
- bool ignoreAutoLink = false;
+ bool getErrorForArchMismatch() const { return passPlugins.getFlag(1); }
+ void setErrorForArchMismatch(bool Value) { passPlugins.setFlag(1, Value); }
+ bool getIgnoreAutoLink() const { return passPlugins.getFlag(2); }
+ void setIgnoreAutoLink(bool Value) { passPlugins.setFlag(2, Value); }
int readWorkers = 0;
// ld64 allows invalid auto link options as long as the link succeeds. LLD
// does not, but there are cases in the wild where the invalid linker options
// exist. This allows users to ignore the specific invalid options in the case
// they can't easily fix them.
llvm::StringSet<> ignoreAutoLinkOptions;
- bool strictAutoLink = false;
+ bool getStrictAutoLink() const { return passPlugins.getFlag(3); }
+ void setStrictAutoLink(bool Value) { passPlugins.setFlag(3, Value); }
PlatformInfo platformInfo;
std::optional<PlatformInfo> secondaryPlatformInfo;
NamespaceKind namespaceKind = NamespaceKind::twolevel;
UndefinedSymbolTreatment undefinedSymbolTreatment =
UndefinedSymbolTreatment::error;
ICFLevel icfLevel = ICFLevel::none;
- bool keepICFStabs = false;
+ bool getKeepICFStabs() const { return mllvmOpts.getFlag(0); }
+ void setKeepICFStabs(bool Value) { mllvmOpts.setFlag(0, Value); }
ObjCStubsMode objcStubsMode = ObjCStubsMode::fast;
llvm::MachO::HeaderFileType outputType;
std::vector<llvm::StringRef> systemLibraryRoots;
std::vector<llvm::StringRef> librarySearchPaths;
std::vector<llvm::StringRef> frameworkSearchPaths;
- bool warnDuplicateRpath = true;
- llvm::SmallVector<llvm::StringRef, 0> runtimePaths;
- llvm::SmallVector<llvm::StringRef, 0> allowableClients;
+ bool getWarnDuplicateRpath() const { return !mllvmOpts.getFlag(1); }
+ void setWarnDuplicateRpath(bool Value) { mllvmOpts.setFlag(1, !Value); }
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> runtimePaths;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> allowableClients;
std::vector<std::string> astPaths;
std::vector<Symbol *> explicitUndefineds;
llvm::StringSet<> explicitDynamicLookups;
@@ -217,34 +226,80 @@ struct Configuration {
// so use a vector instead of a map.
std::vector<SectionAlign> sectionAlignments;
std::vector<SegmentProtection> segmentProtections;
- bool ltoDebugPassManager = false;
- bool emitLLVM = false;
+ bool getLtoDebugPassManager() const { return mllvmOpts.getFlag(2); }
+ void setLtoDebugPassManager(bool Value) { mllvmOpts.setFlag(2, Value); }
+ bool getEmitLLVM() const { return mllvmOpts.getFlag(3); }
+ void setEmitLLVM(bool Value) { mllvmOpts.setFlag(3, Value); }
llvm::StringRef codegenDataGeneratePath;
- bool csProfileGenerate = false;
+ bool getCsProfileGenerate() const {
+ return bpCompressionSortSpecs.getFlag(0);
+ }
+ void setCsProfileGenerate(bool Value) {
+ bpCompressionSortSpecs.setFlag(0, Value);
+ }
llvm::StringRef csProfilePath;
bool pgoWarnMismatch;
bool warnThinArchiveMissingMembers;
bool warnMissingSubsectionsViaSymbols = false;
bool disableVerify;
- bool separateCstringLiteralSections;
- bool tailMergeStrings;
+ bool getSeparateCstringLiteralSections() const {
+ return bpCompressionSortSpecs.getFlag(1);
+ }
+ void setSeparateCstringLiteralSections(bool Value) {
+ bpCompressionSortSpecs.setFlag(1, Value);
+ }
+ bool getTailMergeStrings() const { return bpCompressionSortSpecs.getFlag(2); }
+ void setTailMergeStrings(bool Value) {
+ bpCompressionSortSpecs.setFlag(2, Value);
+ }
unsigned slopScale = 256;
- bool callGraphProfileSort = false;
+ bool getCallGraphProfileSort() const {
+ return bpCompressionSortSpecs.getFlag(3);
+ }
+ void setCallGraphProfileSort(bool Value) {
+ bpCompressionSortSpecs.setFlag(3, Value);
+ }
llvm::StringRef printSymbolOrder;
llvm::StringRef irpgoProfilePath;
- bool bpStartupFunctionSort = false;
- bool bpCompressionSortStartupFunctions = false;
- bool bpFunctionOrderForCompression = false;
- bool bpDataOrderForCompression = false;
- llvm::SmallVector<BPCompressionSortSpec> bpCompressionSortSpecs;
- bool bpVerboseSectionOrderer = false;
+ bool getBpStartupFunctionSort() const { return allowableClients.getFlag(0); }
+ void setBpStartupFunctionSort(bool Value) {
+ allowableClients.setFlag(0, Value);
+ }
+ bool getBpCompressionSortStartupFunctions() const {
+ return allowableClients.getFlag(1);
+ }
+ void setBpCompressionSortStartupFunctions(bool Value) {
+ allowableClients.setFlag(1, Value);
+ }
+ bool getBpFunctionOrderForCompression() const {
+ return allowableClients.getFlag(2);
+ }
+ void setBpFunctionOrderForCompression(bool Value) {
+ allowableClients.setFlag(2, Value);
+ }
+ bool getBpDataOrderForCompression() const {
+ return allowableClients.getFlag(3);
+ }
+ void setBpDataOrderForCompression(bool Value) {
+ allowableClients.setFlag(3, Value);
+ }
+ llvm::SmallVectorWithFlags<BPCompressionSortSpec,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ BPCompressionSortSpec>::value,
+ 4>
+ bpCompressionSortSpecs;
+ bool getBpVerboseSectionOrderer() const { return runtimePaths.getFlag(0); }
+ void setBpVerboseSectionOrderer(bool Value) {
+ runtimePaths.setFlag(0, Value);
+ }
SectionRenameMap sectionRenameMap;
SegmentRenameMap segmentRenameMap;
- bool hasExplicitExports = false;
+ bool getHasExplicitExports() const { return runtimePaths.getFlag(1); }
+ void setHasExplicitExports(bool Value) { runtimePaths.setFlag(1, Value); }
SymbolPatterns exportedSymbols;
SymbolPatterns unexportedSymbols;
SymbolPatterns whyLive;
@@ -253,11 +308,16 @@ struct Configuration {
SymtabPresence localSymbolsPresence = SymtabPresence::All;
SymbolPatterns localSymbolPatterns;
- llvm::SmallVector<llvm::StringRef, 0> mllvmOpts;
- llvm::SmallVector<llvm::StringRef, 0> passPlugins;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> mllvmOpts;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> passPlugins;
- bool zeroModTime = true;
- bool generateUuid = true;
+ bool getZeroModTime() const { return !runtimePaths.getFlag(2); }
+ bool setZeroModTime(bool Value) {
+ runtimePaths.setFlag(2, !Value);
+ return Value;
+ }
+ bool getGenerateUuid() const { return !runtimePaths.getFlag(3); }
+ void setGenerateUuid(bool Value) { runtimePaths.setFlag(3, !Value); }
llvm::StringRef osoPrefix;
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 0dfced91c511d..be13618272466 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -580,11 +580,11 @@ static DenseSet<StringRef> loadedObjectFrameworks;
static void applyDylibMetadata(InputFile *file, bool isNeeded, bool isWeak,
bool isReexport) {
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(file)) {
- dylibFile->forceNeeded |= isNeeded;
- dylibFile->forceWeakImport |= isWeak;
+ dylibFile->setForceNeeded(dylibFile->getForceNeeded() | (isNeeded));
+ dylibFile->setForceWeakImport(dylibFile->getForceWeakImport() | (isWeak));
if (isReexport) {
config->hasReexports = true;
- dylibFile->reexport = true;
+ dylibFile->setReexport(true);
}
}
}
@@ -661,7 +661,7 @@ static void addFramework(StringRef name, bool isNeeded, bool isWeak,
void macho::parseLCLinkerOption(
llvm::SmallVectorImpl<StringRef> &LCLinkerOptions, InputFile *f,
unsigned argc, StringRef data) {
- if (config->ignoreAutoLink)
+ if (config->getIgnoreAutoLink())
return;
SmallVector<StringRef, 4> argv;
@@ -766,7 +766,7 @@ static bool markReexport(StringRef searchName, ArrayRef<StringRef> extensions) {
StringRef filename = path::filename(dylibFile->getName());
if (filename.consume_front(searchName) &&
(filename.empty() || llvm::is_contained(extensions, filename))) {
- dylibFile->reexport = true;
+ dylibFile->setReexport(true);
return true;
}
}
@@ -1679,7 +1679,7 @@ static void createAliases() {
static void handleExplicitExports() {
static constexpr int kMaxWarnings = 3;
- if (config->hasExplicitExports) {
+ if (config->getHasExplicitExports()) {
std::atomic<uint64_t> warningsCount{0};
parallelForEach(symtab->getSymbols(), [&warningsCount](Symbol *sym) {
if (auto *defined = dyn_cast<Defined>(sym)) {
@@ -1732,7 +1732,7 @@ static SmallVector<StringRef, 0> getRuntimePaths(opt::InputArgList &args) {
StringRef val = arg->getValue();
if (seen.insert(val).second)
vals.push_back(val);
- else if (config->warnDuplicateRpath)
+ else if (config->getWarnDuplicateRpath())
warn("duplicate -rpath '" + val + "' ignored [--warn-duplicate-rpath]");
}
return vals;
@@ -1957,7 +1957,10 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
config->printEachFile = args.hasArg(OPT_t);
config->printWhyLoad = args.hasArg(OPT_why_load);
config->omitDebugInfo = args.hasArg(OPT_S);
- config->errorForArchMismatch = args.hasArg(OPT_arch_errors_fatal);
+ [&] {
+ auto PackedFlagValue = args.hasArg(OPT_arch_errors_fatal);
+ return config->setErrorForArchMismatch(PackedFlagValue);
+ }();
if (const Arg *arg = args.getLastArg(OPT_bundle_loader)) {
if (config->outputType != MH_BUNDLE)
error("-bundle_loader can only be used with MachO bundle output");
@@ -2009,10 +2012,13 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
error("--thinlto-prefix-replace=old_dir;new_dir;obj_dir must be used with "
"--thinlto-index-only=");
}
- config->warnDuplicateRpath =
- args.hasFlag(OPT_warn_duplicate_rpath, OPT_no_warn_duplicate_rpath, true);
- config->runtimePaths = getRuntimePaths(args);
- config->allowableClients = getAllowableClients(args);
+ [&] {
+ auto PackedFlagValue = args.hasFlag(OPT_warn_duplicate_rpath,
+ OPT_no_warn_duplicate_rpath, true);
+ return config->setWarnDuplicateRpath(PackedFlagValue);
+ }();
+ config->runtimePaths.assign(getRuntimePaths(args));
+ config->allowableClients.assign(getAllowableClients(args));
config->allLoad = args.hasFlag(OPT_all_load, OPT_noall_load, false);
config->archMultiple = args.hasArg(OPT_arch_multiple);
config->applicationExtension = args.hasFlag(
@@ -2032,7 +2038,10 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
config->emitChainedFixups || args.hasArg(OPT_init_offsets);
config->emitRelativeMethodLists = shouldEmitRelativeMethodLists(args);
config->icfLevel = getICFLevel(args);
- config->keepICFStabs = args.hasArg(OPT_keep_icf_stabs);
+ [&] {
+ auto PackedFlagValue = args.hasArg(OPT_keep_icf_stabs);
+ return config->setKeepICFStabs(PackedFlagValue);
+ }();
config->dedupStrings =
args.hasFlag(OPT_deduplicate_strings, OPT_no_deduplicate_strings, true);
config->dedupSymbolStrings = !args.hasArg(OPT_no_deduplicate_symbol_strings);
@@ -2043,21 +2052,41 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
config->warnDylibInstallName = args.hasFlag(
OPT_warn_dylib_install_name, OPT_no_warn_dylib_install_name, false);
config->ignoreOptimizationHints = args.hasArg(OPT_ignore_optimization_hints);
- config->callGraphProfileSort = args.hasFlag(
- OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true);
+ [&] {
+ auto PackedFlagValue = args.hasFlag(OPT_call_graph_profile_sort,
+ OPT_no_call_graph_profile_sort, true);
+ return config->setCallGraphProfileSort(PackedFlagValue);
+ }();
config->printSymbolOrder = args.getLastArgValue(OPT_print_symbol_order_eq);
- config->forceExactCpuSubtypeMatch =
- getenv("LD_DYLIB_CPU_SUBTYPES_MUST_MATCH");
+ [&] {
+ auto PackedFlagValue = getenv("LD_DYLIB_CPU_SUBTYPES_MUST_MATCH");
+ return config->setForceExactCpuSubtypeMatch(PackedFlagValue);
+ }();
config->objcStubsMode = getObjCStubsMode(args);
- config->ignoreAutoLink = args.hasArg(OPT_ignore_auto_link);
+ [&] {
+ auto PackedFlagValue = args.hasArg(OPT_ignore_auto_link);
+ return config->setIgnoreAutoLink(PackedFlagValue);
+ }();
for (const Arg *arg : args.filtered(OPT_ignore_auto_link_option))
config->ignoreAutoLinkOptions.insert(arg->getValue());
- config->strictAutoLink = args.hasArg(OPT_strict_auto_link);
- config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
- config->emitLLVM = args.hasArg(OPT_lto_emit_llvm);
+ [&] {
+ auto PackedFlagValue = args.hasArg(OPT_strict_auto_link);
+ return config->setStrictAutoLink(PackedFlagValue);
+ }();
+ [&] {
+ auto PackedFlagValue = args.hasArg(OPT_lto_debug_pass_manager);
+ return config->setLtoDebugPassManager(PackedFlagValue);
+ }();
+ [&] {
+ auto PackedFlagValue = args.hasArg(OPT_lto_emit_llvm);
+ return config->setEmitLLVM(PackedFlagValue);
+ }();
config->codegenDataGeneratePath =
args.getLastArgValue(OPT_codegen_data_generate_path);
- config->csProfileGenerate = args.hasArg(OPT_cs_profile_generate);
+ [&] {
+ auto PackedFlagValue = args.hasArg(OPT_cs_profile_generate);
+ return config->setCsProfileGenerate(PackedFlagValue);
+ }();
config->csProfilePath = args.getLastArgValue(OPT_cs_profile_path);
config->pgoWarnMismatch =
args.hasFlag(OPT_pgo_warn_mismatch, OPT_no_pgo_warn_mismatch, true);
@@ -2067,13 +2096,22 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
config->warnMissingSubsectionsViaSymbols =
args.hasFlag(OPT_warn_missing_subsections_via_symbols,
OPT_no_warn_missing_subsections_via_symbols, false);
- config->generateUuid = !args.hasArg(OPT_no_uuid);
+ [&] {
+ auto PackedFlagValue = !args.hasArg(OPT_no_uuid);
+ return config->setGenerateUuid(PackedFlagValue);
+ }();
config->disableVerify = args.hasArg(OPT_disable_verify);
- config->separateCstringLiteralSections =
- args.hasFlag(OPT_separate_cstring_literal_sections,
- OPT_no_separate_cstring_literal_sections, false);
- config->tailMergeStrings =
- args.hasFlag(OPT_tail_merge_strings, OPT_no_tail_merge_strings, false);
+ [&] {
+ auto PackedFlagValue =
+ args.hasFlag(OPT_separate_cstring_literal_sections,
+ OPT_no_separate_cstring_literal_sections, false);
+ return config->setSeparateCstringLiteralSections(PackedFlagValue);
+ }();
+ [&] {
+ auto PackedFlagValue =
+ args.hasFlag(OPT_tail_merge_strings, OPT_no_tail_merge_strings, false);
+ return config->setTailMergeStrings(PackedFlagValue);
+ }();
if (auto *arg = args.getLastArg(OPT_slop_scale_eq)) {
StringRef v(arg->getValue());
unsigned slop = 0;
@@ -2085,7 +2123,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
auto IncompatWithCGSort = [&](StringRef firstArgStr) {
// Throw an error only if --call-graph-profile-sort is explicitly specified
- if (config->callGraphProfileSort)
+ if (config->getCallGraphProfileSort())
if (const Arg *arg = args.getLastArgNoClaim(OPT_call_graph_profile_sort))
error(firstArgStr + " is incompatible with " + arg->getSpelling());
};
@@ -2098,27 +2136,30 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
if (const Arg *arg = args.getLastArg(OPT_irpgo_profile_sort)) {
config->irpgoProfilePath = arg->getValue();
- config->bpStartupFunctionSort = true;
+ config->setBpStartupFunctionSort(true);
IncompatWithCGSort(arg->getSpelling());
}
- config->bpCompressionSortStartupFunctions =
- args.hasFlag(OPT_bp_compression_sort_startup_functions,
- OPT_no_bp_compression_sort_startup_functions, false);
+ [&] {
+ auto PackedFlagValue =
+ args.hasFlag(OPT_bp_compression_sort_startup_functions,
+ OPT_no_bp_compression_sort_startup_functions, false);
+ return config->setBpCompressionSortStartupFunctions(PackedFlagValue);
+ }();
if (const Arg *arg = args.getLastArg(OPT_bp_startup_sort)) {
StringRef startupSortStr = arg->getValue();
if (startupSortStr == "function") {
- config->bpStartupFunctionSort = true;
+ config->setBpStartupFunctionSort(true);
} else if (startupSortStr != "none") {
error("unknown value `" + startupSortStr + "` for " + arg->getSpelling());
}
if (startupSortStr != "none")
IncompatWithCGSort(arg->getSpelling());
}
- if (!config->bpStartupFunctionSort &&
- config->bpCompressionSortStartupFunctions)
+ if (!config->getBpStartupFunctionSort() &&
+ config->getBpCompressionSortStartupFunctions())
error("--bp-compression-sort-startup-functions must be used with "
"--bp-startup-sort=function");
- if (config->irpgoProfilePath.empty() && config->bpStartupFunctionSort)
+ if (config->irpgoProfilePath.empty() && config->getBpStartupFunctionSort())
error("--bp-startup-sort=function must be used with "
"--irpgo-profile");
auto addCompressionSortSpec = [&](StringRef value) {
@@ -2168,12 +2209,12 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
if (const Arg *arg = args.getLastArg(OPT_bp_compression_sort)) {
StringRef compressionSortStr = arg->getValue();
if (compressionSortStr == "function") {
- config->bpFunctionOrderForCompression = true;
+ config->setBpFunctionOrderForCompression(true);
} else if (compressionSortStr == "data") {
- config->bpDataOrderForCompression = true;
+ config->setBpDataOrderForCompression(true);
} else if (compressionSortStr == "both") {
- config->bpFunctionOrderForCompression = true;
- config->bpDataOrderForCompression = true;
+ config->setBpFunctionOrderForCompression(true);
+ config->setBpDataOrderForCompression(true);
} else if (compressionSortStr != "none") {
error("unknown value `" + compressionSortStr + "` for " +
arg->getSpelling());
@@ -2181,7 +2222,10 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
if (compressionSortStr != "none")
IncompatWithCGSort(arg->getSpelling());
}
- config->bpVerboseSectionOrderer = args.hasArg(OPT_verbose_bp_section_orderer);
+ [&] {
+ auto PackedFlagValue = args.hasArg(OPT_verbose_bp_section_orderer);
+ return config->setBpVerboseSectionOrderer(PackedFlagValue);
+ }();
for (const Arg *arg : args.filtered(OPT_alias)) {
config->aliasedSymbols.push_back(
@@ -2189,9 +2233,12 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
}
if (const char *zero = getenv("ZERO_AR_DATE"))
- config->zeroModTime = strcmp(zero, "0") != 0;
+ [&] {
+ auto PackedFlagValue = strcmp(zero, "0") != 0;
+ return config->setZeroModTime(PackedFlagValue);
+ }();
if (args.getLastArg(OPT_reproducible))
- config->zeroModTime = true;
+ config->setZeroModTime(true);
std::array<PlatformType, 4> encryptablePlatforms{
PLATFORM_IOS, PLATFORM_WATCHOS, PLATFORM_TVOS, PLATFORM_XROS};
@@ -2304,14 +2351,17 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
config->segmentProtections.push_back({segName, maxProt, initProt});
}
- config->hasExplicitExports =
- args.hasArg(OPT_no_exported_symbols) ||
- args.hasArgNoClaim(OPT_exported_symbol, OPT_exported_symbols_list);
+ [&] {
+ auto PackedFlagValue =
+ args.hasArg(OPT_no_exported_symbols) ||
+ args.hasArgNoClaim(OPT_exported_symbol, OPT_exported_symbols_list);
+ return config->setHasExplicitExports(PackedFlagValue);
+ }();
handleSymbolPatterns(args, config->exportedSymbols, OPT_exported_symbol,
OPT_exported_symbols_list);
handleSymbolPatterns(args, config->unexportedSymbols, OPT_unexported_symbol,
OPT_unexported_symbols_list);
- if (config->hasExplicitExports && !config->unexportedSymbols.empty())
+ if (config->getHasExplicitExports() && !config->unexportedSymbols.empty())
error("cannot use both -exported_symbol* and -unexported_symbol* options");
if (args.hasArg(OPT_no_exported_symbols) && !config->exportedSymbols.empty())
@@ -2439,7 +2489,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
config->mllvmOpts.emplace_back(arg->getValue());
}
- config->passPlugins = args::getStrings(args, OPT_load_pass_plugins);
+ config->passPlugins.assign(args::getStrings(args, OPT_load_pass_plugins));
createSyntheticSections();
createSyntheticSymbols();
@@ -2458,7 +2508,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
// If either --thinlto-index-only or --lto-emit-llvm is given, we should
// not create object files. Index file creation is already done in
// compileBitcodeFiles, so we are done if that's the case.
- if (config->thinLTOIndexOnly || config->emitLLVM)
+ if (config->thinLTOIndexOnly || config->getEmitLLVM())
return errorCount() == 0;
// LTO may emit a non-hidden (extern) object file symbol even if the
@@ -2500,7 +2550,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
if (!config->codegenDataGeneratePath.empty())
codegenDataGenerate();
- if (config->callGraphProfileSort)
+ if (config->getCallGraphProfileSort())
priorityBuilder.extractCallGraphProfile();
if (config->deadStrip)
@@ -2554,7 +2604,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
timeTraceProfilerCleanup();
}
- if (errorCount() != 0 || config->strictAutoLink)
+ if (errorCount() != 0 || config->getStrictAutoLink())
for (const auto &warning : missingAutolinkWarnings)
warn(warning);
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index e097d2ce302c3..0ed3de9731900 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -354,7 +354,7 @@ StringRef macho::rerootPath(StringRef path) {
}
uint32_t macho::getModTime(StringRef path) {
- if (config->zeroModTime)
+ if (config->getZeroModTime())
return 0;
fs::file_status stat;
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 09ab6b17cfda9..72eefba931f42 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -192,7 +192,7 @@ static bool compatWithTargetArch(const InputFile *file, const Header *hdr) {
if (hdr->cputype != cpuType) {
Architecture arch =
getArchitectureFromCpuType(hdr->cputype, hdr->cpusubtype);
- auto msg = config->errorForArchMismatch
+ auto msg = config->getErrorForArchMismatch()
? static_cast<void (*)(const Twine &)>(error)
: warn;
@@ -395,7 +395,7 @@ void ObjFile::parseSections(ArrayRef<SectionHeader> sectionHeaders) {
segname == segment_names::text) {
splitEhFrames(data, *sections.back());
} else if (segname == segment_names::llvm) {
- if (config->callGraphProfileSort && name == section_names::cgProfile)
+ if (config->getCallGraphProfileSort() && name == section_names::cgProfile)
checkError(parseCallGraph(data, callGraph));
// ld64 does not appear to emit contents from sections within the __LLVM
// segment. Symbols within those sections point to bitcode metadata
@@ -1829,8 +1829,10 @@ void DylibFile::loadReexport(StringRef path, DylibFile *umbrella,
DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
bool isBundleLoader, bool explicitlyLinked)
- : InputFile(DylibKind, mb), refState(RefState::Unreferenced),
- explicitlyLinked(explicitlyLinked), isBundleLoader(isBundleLoader) {
+ : InputFile(DylibKind, mb),
+ rpaths(decltype(this->rpaths)::withFlags(
+ unsigned(explicitlyLinked) | (unsigned(isBundleLoader) << 1))),
+ refState(RefState::Unreferenced) {
assert(!isBundleLoader || !umbrella);
if (umbrella == nullptr)
umbrella = this;
@@ -1856,7 +1858,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
message(toString(this));
inputFiles.insert(this);
- deadStrippable = hdr->flags & MH_DEAD_STRIPPABLE_DYLIB;
+ setDeadStrippable(hdr->flags & MH_DEAD_STRIPPABLE_DYLIB);
if (!checkCompatibility(this))
return;
@@ -2001,7 +2003,7 @@ static bool isTargetPlatformArchCompatible(
if (is_contained(interfaceTargets, target))
return true;
- if (config->forceExactCpuSubtypeMatch)
+ if (config->getForceExactCpuSubtypeMatch())
return false;
ArchitectureSet archSet;
@@ -2016,8 +2018,10 @@ static bool isTargetPlatformArchCompatible(
DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
bool isBundleLoader, bool explicitlyLinked)
- : InputFile(DylibKind, interface), refState(RefState::Unreferenced),
- explicitlyLinked(explicitlyLinked), isBundleLoader(isBundleLoader) {
+ : InputFile(DylibKind, interface),
+ rpaths(decltype(this->rpaths)::withFlags(
+ unsigned(explicitlyLinked) | (unsigned(isBundleLoader) << 1))),
+ refState(RefState::Unreferenced) {
// FIXME: Add test for the missing TBD code path.
if (umbrella == nullptr)
@@ -2110,8 +2114,8 @@ DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
}
DylibFile::DylibFile(DylibFile *umbrella)
- : InputFile(DylibKind, MemoryBufferRef{}), refState(RefState::Unreferenced),
- explicitlyLinked(false), isBundleLoader(false) {
+ : InputFile(DylibKind, MemoryBufferRef{}),
+ refState(RefState::Unreferenced) {
if (umbrella == nullptr)
umbrella = this;
this->umbrella = umbrella;
@@ -2129,7 +2133,7 @@ void DylibFile::parseReexports(const InterfaceFile &interface) {
}
bool DylibFile::isExplicitlyLinked() const {
- if (!explicitlyLinked)
+ if (!getExplicitlyLinkedFlag())
return false;
// If this dylib was explicitly linked, but at least one of the symbols
@@ -2363,7 +2367,7 @@ static Expected<InputFile *>
loadArchiveMember(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName,
uint64_t offsetInArchive, bool forceHidden, bool compatArch,
bool lazy) {
- if (config->zeroModTime)
+ if (config->getZeroModTime())
modTime = 0;
switch (identify_magic(mb.getBuffer())) {
diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
index f1cebd10bf76e..4b105526a97b4 100644
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -11,6 +11,7 @@
#include "MachOStructs.h"
#include "Target.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "lld/Common/DWARF.h"
#include "lld/Common/LLVM.h"
@@ -235,34 +236,45 @@ class DylibFile final : public InputFile {
void parseReexports(const llvm::MachO::InterfaceFile &interface);
bool isReferenced() const { return numReferencedSymbols > 0; }
bool isExplicitlyLinked() const;
- void setExplicitlyLinked() { explicitlyLinked = true; }
+ void setExplicitlyLinked() { setExplicitlyLinkedFlag(true); }
static bool classof(const InputFile *f) { return f->kind() == DylibKind; }
StringRef installName;
DylibFile *exportingFile = nullptr;
DylibFile *umbrella;
- SmallVector<StringRef, 2> rpaths;
- SmallVector<StringRef> allowableClients;
+ llvm::SmallVectorWithFlags<StringRef, 2, 2> rpaths;
+ llvm::SmallVectorWithFlags<
+ StringRef,
+ llvm::CalculateSmallVectorDefaultInlinedElements<StringRef>::value, 4>
+ allowableClients;
uint32_t compatibilityVersion = 0;
uint32_t currentVersion = 0;
int64_t ordinal = 0; // Ordinal numbering starts from 1, so 0 is a sentinel
unsigned numReferencedSymbols = 0;
RefState refState;
- bool reexport = false;
- bool forceNeeded = false;
- bool forceWeakImport = false;
- bool deadStrippable = false;
+ bool getReexport() const { return allowableClients.getFlag(0); }
+ void setReexport(bool Value) { allowableClients.setFlag(0, Value); }
+ bool getForceNeeded() const { return allowableClients.getFlag(1); }
+ void setForceNeeded(bool Value) { allowableClients.setFlag(1, Value); }
+ bool getForceWeakImport() const { return allowableClients.getFlag(2); }
+ void setForceWeakImport(bool Value) { allowableClients.setFlag(2, Value); }
+ bool getDeadStrippable() const { return allowableClients.getFlag(3); }
+ void setDeadStrippable(bool Value) { allowableClients.setFlag(3, Value); }
private:
- bool explicitlyLinked = false; // Access via isExplicitlyLinked().
+ bool getExplicitlyLinkedFlag() const { return rpaths.getFlag(0); }
+ void setExplicitlyLinkedFlag(bool Value) {
+ rpaths.setFlag(0, Value);
+ } // Access via isExplicitlyLinked().
public:
// An executable can be used as a bundle loader that will load the output
// file being linked, and that contains symbols referenced, but not
// implemented in the bundle. When used like this, it is very similar
// to a dylib, so we've used the same class to represent it.
- bool isBundleLoader;
+ bool getIsBundleLoader() const { return rpaths.getFlag(1); }
+ void setIsBundleLoader(bool Value) { rpaths.setFlag(1, Value); }
// Synthetic Dylib objects created by $ld$previous symbols in this dylib.
// Usually empty. These synthetic dylibs won't have synthetic dylibs
diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp
index 6ea4b0ddd58e4..19d77715faf0d 100644
--- a/lld/MachO/InputSection.cpp
+++ b/lld/MachO/InputSection.cpp
@@ -63,7 +63,7 @@ void lld::macho::addInputSection(InputSection *inputSection) {
isec->parent = osec;
inputSections.push_back(isec);
} else if (auto *isec = dyn_cast<CStringInputSection>(inputSection)) {
- bool useSectionName = config->separateCstringLiteralSections ||
+ bool useSectionName = config->getSeparateCstringLiteralSections() ||
isec->getName() == section_names::objcMethname;
auto *osec = in.getOrCreateCStringSection(
useSectionName ? isec->getName() : section_names::cString);
diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index 701d81cd5d027..6a55479d366a7 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -55,9 +55,9 @@ static lto::Config createConfig() {
c.TimeTraceEnabled = config->timeTraceEnabled;
c.TimeTraceGranularity = config->timeTraceGranularity;
- c.DebugPassManager = config->ltoDebugPassManager;
+ c.DebugPassManager = config->getLtoDebugPassManager();
c.CSIRProfile = std::string(config->csProfilePath);
- c.RunCSIRInstr = config->csProfileGenerate;
+ c.RunCSIRInstr = config->getCsProfileGenerate();
c.PGOWarnMismatch = config->pgoWarnMismatch;
c.DisableVerify = config->disableVerify;
c.OptLevel = config->ltoo;
@@ -70,7 +70,7 @@ static lto::Config createConfig() {
checkError(c.addSaveTemps(config->outputFile.str() + ".",
/*UseInputModulePath=*/true));
- if (config->emitLLVM) {
+ if (config->getEmitLLVM()) {
llvm::StringRef outputFile = config->outputFile;
c.PreCodeGenModuleHook = [outputFile](size_t task, const Module &m) {
if (std::unique_ptr<raw_fd_ostream> os = openLTOOutputFile(outputFile))
diff --git a/lld/MachO/SectionPriorities.cpp b/lld/MachO/SectionPriorities.cpp
index dea47c76a385e..4f77a26116e45 100644
--- a/lld/MachO/SectionPriorities.cpp
+++ b/lld/MachO/SectionPriorities.cpp
@@ -372,17 +372,19 @@ void macho::PriorityBuilder::parseOrderFile(StringRef path) {
DenseMap<const InputSection *, int>
macho::PriorityBuilder::buildInputSectionPriorities() {
DenseMap<const InputSection *, int> sectionPriorities;
- if (config->bpStartupFunctionSort || config->bpFunctionOrderForCompression ||
- config->bpDataOrderForCompression ||
+ if (config->getBpStartupFunctionSort() ||
+ config->getBpFunctionOrderForCompression() ||
+ config->getBpDataOrderForCompression() ||
!config->bpCompressionSortSpecs.empty()) {
TimeTraceScope timeScope("Balanced Partitioning Section Orderer");
sectionPriorities = runBalancedPartitioning(
- config->bpStartupFunctionSort ? config->irpgoProfilePath : "",
- config->bpCompressionSortSpecs, config->bpFunctionOrderForCompression,
- config->bpDataOrderForCompression,
- config->bpCompressionSortStartupFunctions,
- config->bpVerboseSectionOrderer);
- } else if (config->callGraphProfileSort) {
+ config->getBpStartupFunctionSort() ? config->irpgoProfilePath : "",
+ config->bpCompressionSortSpecs,
+ config->getBpFunctionOrderForCompression(),
+ config->getBpDataOrderForCompression(),
+ config->getBpCompressionSortStartupFunctions(),
+ config->getBpVerboseSectionOrderer());
+ } else if (config->getCallGraphProfileSort()) {
// Sort sections by the profile data provided by __LLVM,__cg_profile
// sections.
//
diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h
index cdeef93475222..6409e4f6b0e54 100644
--- a/lld/MachO/Symbols.h
+++ b/lld/MachO/Symbols.h
@@ -276,7 +276,7 @@ class DylibSymbol : public Symbol {
// Symbols from weak libraries/frameworks are also weakly-referenced.
bool isWeakRef() const override {
return refState == RefState::Weak ||
- (file && getFile()->umbrella->forceWeakImport);
+ (file && getFile()->umbrella->getForceWeakImport());
}
bool isReferenced() const { return refState != RefState::Unreferenced; }
bool isTlv() const override { return tlv; }
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index cc7aaa2c7ee9f..5edeee940d7a6 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1234,7 +1234,7 @@ void SymtabSection::emitStabs() {
// Constant-folded symbols go in the executable's symbol table, but don't
// get a stabs entry unless --keep-icf-stabs flag is specified.
- if (!config->keepICFStabs &&
+ if (!config->getKeepICFStabs() &&
defined->identicalCodeFoldingKind != Symbol::ICFFoldKind::None)
continue;
@@ -1761,7 +1761,7 @@ void DeduplicatedCStringSection::finalizeContents() {
assert(isec.align != 0);
auto align = getStringPieceAlignment(isec, piece);
auto [it, wasInserted] = strToAlignment.try_emplace(s, align);
- if (config->tailMergeStrings && wasInserted)
+ if (config->getTailMergeStrings() && wasInserted)
deduplicatedStrs.push_back(s);
if (!wasInserted && it->second < align)
it->second = align;
@@ -1812,8 +1812,8 @@ void DeduplicatedCStringSection::finalizeContents() {
auto s = isec.getCachedHashStringRef(pieceIdx);
// Any string can be tail merged with itself with an offset of zero
uint64_t tailMergeOffset = 0;
- auto mergeIt =
- config->tailMergeStrings ? tailMergeMap.find(s) : tailMergeMap.end();
+ auto mergeIt = config->getTailMergeStrings() ? tailMergeMap.find(s)
+ : tailMergeMap.end();
if (mergeIt != tailMergeMap.end()) {
auto &[superString, offset] = mergeIt->second;
// s can be tail merged with superString. Do not layout s. Instead layout
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index b97203d656ebd..2e522bba4b10e 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -862,7 +862,7 @@ template <class LP> void Writer::createLoadCommands() {
llvm_unreachable("unhandled output file type");
}
- if (config->generateUuid) {
+ if (config->getGenerateUuid()) {
uuidCommand = make<LCUuid>();
in.header->addLoadCommand(uuidCommand);
}
@@ -896,11 +896,11 @@ template <class LP> void Writer::createLoadCommands() {
dylibFiles[i]->extraDylibs.end());
for (DylibFile *dylibFile : dylibFiles) {
- if (dylibFile->isBundleLoader) {
+ if (dylibFile->getIsBundleLoader()) {
dylibFile->ordinal = BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE;
// Shortcut since bundle-loader does not re-export the symbols.
- dylibFile->reexport = false;
+ dylibFile->setReexport(false);
continue;
}
@@ -912,8 +912,8 @@ template <class LP> void Writer::createLoadCommands() {
// FIXME: `isReferenced()` is currently computed before dead code
// stripping, so references from dead code keep a dylib alive. This
// matches ld64, but it's something we should do better.
- if (!dylibFile->isReferenced() && !dylibFile->forceNeeded &&
- (!dylibFile->isExplicitlyLinked() || dylibFile->deadStrippable ||
+ if (!dylibFile->isReferenced() && !dylibFile->getForceNeeded() &&
+ (!dylibFile->isExplicitlyLinked() || dylibFile->getDeadStrippable() ||
config->deadStripDylibs))
continue;
@@ -945,13 +945,13 @@ template <class LP> void Writer::createLoadCommands() {
ordinal = dylibFile->ordinal = dylibOrdinal++;
LoadCommandType lcType = LC_LOAD_DYLIB;
- if (dylibFile->reexport) {
- if (dylibFile->forceWeakImport)
+ if (dylibFile->getReexport()) {
+ if (dylibFile->getForceWeakImport())
warn(path::filename(dylibFile->getName()) +
" is re-exported so cannot be weak-linked");
lcType = LC_REEXPORT_DYLIB;
- } else if (dylibFile->forceWeakImport ||
+ } else if (dylibFile->getForceWeakImport() ||
dylibFile->refState == RefState::Weak) {
lcType = LC_LOAD_WEAK_DYLIB;
}
@@ -1358,7 +1358,7 @@ void Writer::writeOutputFile() {
writeSections();
applyOptimizationHints();
buildFixupChains();
- if (config->generateUuid)
+ if (config->getGenerateUuid())
writeUuid();
writeCodeSignature();
diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h
index 260df6f9b8e24..4dcbcd75f79be 100644
--- a/lld/wasm/Config.h
+++ b/lld/wasm/Config.h
@@ -10,6 +10,7 @@
#define LLD_WASM_CONFIG_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
@@ -60,14 +61,27 @@ struct Config {
bool disableVerify;
bool emitRelocs;
bool exportAll;
- bool exportDynamic;
- bool exportTable;
- bool extendedConst;
- bool growableTable;
- bool gcSections;
+ bool getExportDynamic() const { return buildIdVector.getFlag(0); }
+ void setExportDynamic(bool Value) { buildIdVector.setFlag(0, Value); }
+ bool getExportTable() const { return buildIdVector.getFlag(1); }
+ bool setExportTable(bool Value) {
+ buildIdVector.setFlag(1, Value);
+ return Value;
+ }
+ bool getExtendedConst() const { return buildIdVector.getFlag(2); }
+ bool setExtendedConst(bool Value) {
+ buildIdVector.setFlag(2, Value);
+ return Value;
+ }
+ bool getGrowableTable() const { return buildIdVector.getFlag(3); }
+ void setGrowableTable(bool Value) { buildIdVector.setFlag(3, Value); }
+ bool getGcSections() const { return rpath.getFlag(0); }
+ void setGcSections(bool Value) { rpath.setFlag(0, Value); }
llvm::StringSet<> keepSections;
- bool cooperativeThreading;
- bool libcallThreadContext;
+ bool getCooperativeThreading() const { return rpath.getFlag(1); }
+ void setCooperativeThreading(bool Value) { rpath.setFlag(1, Value); }
+ bool getLibcallThreadContext() const { return rpath.getFlag(2); }
+ void setLibcallThreadContext(bool Value) { rpath.setFlag(2, Value); }
std::optional<std::pair<llvm::StringRef, llvm::StringRef>> memoryImport;
std::optional<llvm::StringRef> memoryExport;
bool sharedMemory;
@@ -97,7 +111,8 @@ struct Config {
uint64_t initialHeap;
uint64_t initialMemory;
uint64_t maxMemory;
- bool noGrowableMemory;
+ bool getNoGrowableMemory() const { return rpath.getFlag(3); }
+ void setNoGrowableMemory(bool Value) { rpath.setFlag(3, Value); }
// The table offset at which to place function addresses. We reserve zero
// for the null function pointer. This gets set to 1 for executables and 0
// for shared libraries (since they always added to a dynamic offset at
@@ -109,7 +124,8 @@ struct Config {
unsigned ltoo;
llvm::CodeGenOptLevel ltoCgo;
unsigned optimize;
- bool ltoDebugPassManager;
+ bool getLtoDebugPassManager() const { return searchPaths.getFlag(0); }
+ void setLtoDebugPassManager(bool Value) { searchPaths.setFlag(0, Value); }
UnresolvedPolicy unresolvedSymbols;
BuildIdKind buildId = BuildIdKind::None;
@@ -130,14 +146,16 @@ struct Config {
llvm::StringSet<> allowUndefinedSymbols;
llvm::StringSet<> exportedSymbols;
std::vector<llvm::StringRef> requiredExports;
- llvm::SmallVector<llvm::StringRef, 0> searchPaths;
- llvm::SmallVector<llvm::StringRef, 0> rpath;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0> searchPaths;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 4> rpath;
llvm::CachePruningPolicy thinLTOCachePolicy;
std::optional<std::vector<std::string>> features;
std::optional<std::vector<std::string>> extraFeatures;
- llvm::SmallVector<uint8_t, 0> buildIdVector;
+ llvm::SmallVectorWithFlags<uint8_t, 0, 4> buildIdVector;
- bool isMultithreaded() const { return sharedMemory || cooperativeThreading; }
+ bool isMultithreaded() const {
+ return sharedMemory || getCooperativeThreading();
+ }
};
// The Ctx object hold all other (non-configuration) global state.
@@ -271,19 +289,27 @@ struct Ctx {
WasmSym sym;
// True if we are creating position-independent code.
- bool isPic = false;
+ bool getIsPic() const { return whyExtractRecords.getFlag(0); }
+ void setIsPic(bool Value) { whyExtractRecords.setFlag(0, Value); }
// True if we have an MVP input that uses __indirect_function_table and which
// requires it to be allocated to table number 0.
- bool legacyFunctionTable = false;
+ bool getLegacyFunctionTable() const { return whyExtractRecords.getFlag(1); }
+ void setLegacyFunctionTable(bool Value) {
+ whyExtractRecords.setFlag(1, Value);
+ }
// Will be set to true if bss data segments should be emitted. In most cases
// this is not necessary.
- bool emitBssSegments = false;
+ bool getEmitBssSegments() const { return whyExtractRecords.getFlag(2); }
+ bool setEmitBssSegments(bool Value) {
+ whyExtractRecords.setFlag(2, Value);
+ return Value;
+ }
// A tuple of (reference, extractedFile, sym). Used by --why-extract=.
- llvm::SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>,
- 0>
+ llvm::SmallVectorWithFlags<
+ std::tuple<std::string, const InputFile *, const Symbol &>, 0, 3>
whyExtractRecords;
Ctx();
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 86ade0fc419b2..b9b3a217a0964 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -66,9 +66,9 @@ void Ctx::reset() {
syntheticGlobals.clear();
syntheticTables.clear();
whyExtractRecords.clear();
- isPic = false;
- legacyFunctionTable = false;
- emitBssSegments = false;
+ setIsPic(false);
+ setLegacyFunctionTable(false);
+ setEmitBssSegments(false);
sym = WasmSym{};
}
@@ -507,8 +507,8 @@ static void readConfigs(opt::InputArgList &args) {
ctx.arg.emitRelocs = args.hasArg(OPT_emit_relocs);
ctx.arg.entry = getEntry(args);
ctx.arg.exportAll = args.hasArg(OPT_export_all);
- ctx.arg.exportTable = args.hasArg(OPT_export_table);
- ctx.arg.growableTable = args.hasArg(OPT_growable_table);
+ ctx.arg.setExportTable(args.hasArg(OPT_export_table));
+ ctx.arg.setGrowableTable(args.hasArg(OPT_growable_table));
ctx.arg.noinhibitExec = args.hasArg(OPT_noinhibit_exec);
if (args.hasArg(OPT_import_memory_with_name)) {
@@ -531,7 +531,7 @@ static void readConfigs(opt::InputArgList &args) {
ctx.arg.soName = args.getLastArgValue(OPT_soname);
ctx.arg.importTable = args.hasArg(OPT_import_table);
ctx.arg.importUndefined = args.hasArg(OPT_import_undefined);
- ctx.arg.cooperativeThreading = args.hasArg(OPT_cooperative_threading);
+ ctx.arg.setCooperativeThreading(args.hasArg(OPT_cooperative_threading));
ctx.arg.ltoo = args::getInteger(args, OPT_lto_O, 2);
if (ctx.arg.ltoo > 3)
error("invalid optimization level for LTO: " + Twine(ctx.arg.ltoo));
@@ -543,14 +543,14 @@ static void readConfigs(opt::InputArgList &args) {
error("invalid codegen optimization level for LTO: " + Twine(ltoCgo));
ctx.arg.ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
ctx.arg.ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
- ctx.arg.ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
+ ctx.arg.setLtoDebugPassManager(args.hasArg(OPT_lto_debug_pass_manager));
ctx.arg.mapFile = args.getLastArgValue(OPT_Map);
ctx.arg.optimize = args::getInteger(args, OPT_O, 1);
ctx.arg.outputFile = args.getLastArgValue(OPT_o);
ctx.arg.relocatable = args.hasArg(OPT_relocatable);
- ctx.arg.rpath = args::getStrings(args, OPT_rpath);
- ctx.arg.gcSections =
- args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !ctx.arg.relocatable);
+ ctx.arg.rpath.assign(args::getStrings(args, OPT_rpath));
+ ctx.arg.setGcSections(
+ args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !ctx.arg.relocatable));
for (auto *arg : args.filtered(OPT_keep_section))
ctx.arg.keepSections.insert(arg->getValue());
ctx.arg.mergeDataSegments =
@@ -560,7 +560,7 @@ static void readConfigs(opt::InputArgList &args) {
ctx.arg.printGcSections =
args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
ctx.arg.saveTemps = args.hasArg(OPT_save_temps);
- ctx.arg.searchPaths = args::getStrings(args, OPT_library_path);
+ ctx.arg.searchPaths.assign(args::getStrings(args, OPT_library_path));
ctx.arg.shared = args.hasArg(OPT_shared);
ctx.arg.shlibSigCheck = !args.hasArg(OPT_no_shlib_sigcheck);
ctx.arg.stripAll = args.hasArg(OPT_strip_all);
@@ -606,7 +606,7 @@ static void readConfigs(opt::InputArgList &args) {
ctx.arg.initialHeap = args::getInteger(args, OPT_initial_heap, 0);
ctx.arg.initialMemory = args::getInteger(args, OPT_initial_memory, 0);
ctx.arg.maxMemory = args::getInteger(args, OPT_max_memory, 0);
- ctx.arg.noGrowableMemory = args.hasArg(OPT_no_growable_memory);
+ ctx.arg.setNoGrowableMemory(args.hasArg(OPT_no_growable_memory));
ctx.arg.zStackSize =
args::getZOptionValue(args, OPT_z, "stack-size", WasmDefaultPageSize);
ctx.arg.pageSize = args::getInteger(args, OPT_page_size, WasmDefaultPageSize);
@@ -617,14 +617,14 @@ static void readConfigs(opt::InputArgList &args) {
if (ctx.arg.pie || ctx.arg.shared)
ctx.arg.isStatic = false;
- if (ctx.arg.maxMemory != 0 && ctx.arg.noGrowableMemory) {
+ if (ctx.arg.maxMemory != 0 && ctx.arg.getNoGrowableMemory()) {
// Erroring out here is simpler than defining precedence rules.
error("--max-memory is incompatible with --no-growable-memory");
}
// Default value of exportDynamic depends on `-shared`
- ctx.arg.exportDynamic =
- args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, ctx.arg.shared);
+ ctx.arg.setExportDynamic(
+ args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, ctx.arg.shared));
// Parse wasm32/64.
if (auto *arg = args.getLastArg(OPT_m)) {
@@ -675,7 +675,9 @@ static void readConfigs(opt::InputArgList &args) {
if (args.hasArg(OPT_print_map))
ctx.arg.mapFile = "-";
- std::tie(ctx.arg.buildId, ctx.arg.buildIdVector) = getBuildId(args);
+ auto [BuildId, BuildIdVector] = getBuildId(args);
+ ctx.arg.buildId = BuildId;
+ ctx.arg.buildIdVector.assign(std::move(BuildIdVector));
}
// Some Config members do not directly correspond to any particular
@@ -683,10 +685,10 @@ static void readConfigs(opt::InputArgList &args) {
// This function initialize such members. See Config.h for the details
// of these values.
static void setConfigs() {
- ctx.isPic = ctx.arg.pie || ctx.arg.shared;
+ ctx.setIsPic(ctx.arg.pie || ctx.arg.shared);
- if (ctx.isPic) {
- if (ctx.arg.exportTable)
+ if (ctx.getIsPic()) {
+ if (ctx.arg.getExportTable())
error("-shared/-pie is incompatible with --export-table");
ctx.arg.importTable = true;
} else {
@@ -703,9 +705,9 @@ static void setConfigs() {
}
if (ctx.arg.relocatable) {
- if (ctx.arg.exportTable)
+ if (ctx.arg.getExportTable())
error("--relocatable is incompatible with --export-table");
- if (ctx.arg.growableTable)
+ if (ctx.arg.getGrowableTable())
error("--relocatable is incompatible with --growable-table");
// Ignore any --import-table, as it's redundant.
ctx.arg.importTable = true;
@@ -725,10 +727,10 @@ static void setConfigs() {
if (!ctx.arg.memoryExport.has_value() && !ctx.arg.memoryImport.has_value()) {
ctx.arg.memoryExport = memoryName;
}
- if (ctx.arg.cooperativeThreading) {
+ if (ctx.arg.getCooperativeThreading()) {
if (ctx.arg.sharedMemory)
error("--cooperative-threading is incompatible with --shared-memory");
- ctx.arg.libcallThreadContext = true;
+ ctx.arg.setLibcallThreadContext(true);
// Cooperative threading requires the table is either imported or exported
// or otherwise there's no way for embedders to read spawned functions from
@@ -736,7 +738,7 @@ static void setConfigs() {
// imported (e.g in `isPic` mode) then export the table instead to ensure
// that it's visible to the outside world.
if (!ctx.arg.importTable)
- ctx.arg.exportTable = true;
+ ctx.arg.setExportTable(true);
}
}
@@ -758,13 +760,13 @@ static void checkOptions(opt::InputArgList &args) {
if (ctx.arg.outputFile.empty() && !ctx.arg.thinLTOIndexOnly)
error("no output file specified");
- if (ctx.arg.importTable && ctx.arg.exportTable)
+ if (ctx.arg.importTable && ctx.arg.getExportTable())
error("--import-table and --export-table may not be used together");
if (ctx.arg.relocatable) {
if (!ctx.arg.entry.empty())
error("entry point specified for relocatable output file");
- if (ctx.arg.gcSections)
+ if (ctx.arg.getGcSections())
error("-r and --gc-sections may not be used together");
if (ctx.arg.compressRelocations)
error("-r -and --compress-relocations may not be used together");
@@ -782,7 +784,7 @@ static void checkOptions(opt::InputArgList &args) {
warn("-Bsymbolic is only meaningful when combined with -shared");
}
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
if (ctx.arg.globalBase)
error("--global-base may not be used with -shared/-pie");
if (ctx.arg.tableBase)
@@ -918,10 +920,11 @@ static void createSyntheticSymbols() {
bool is64 = ctx.arg.is64.value_or(false);
- auto stack_pointer_name =
- ctx.arg.libcallThreadContext ? "__init_stack_pointer" : "__stack_pointer";
- if (ctx.isPic) {
- if (ctx.arg.libcallThreadContext) {
+ auto stack_pointer_name = ctx.arg.getLibcallThreadContext()
+ ? "__init_stack_pointer"
+ : "__stack_pointer";
+ if (ctx.getIsPic()) {
+ if (ctx.arg.getLibcallThreadContext()) {
ctx.sym.stackPointer = createUndefinedGlobal(
stack_pointer_name,
ctx.arg.is64.value_or(false) ? &globalTypeI64 : &globalTypeI32);
@@ -943,14 +946,14 @@ static void createSyntheticSymbols() {
ctx.sym.tableBase->markLive();
} else {
// For non-PIC code
- ctx.sym.stackPointer =
- createGlobalVariable(stack_pointer_name, !ctx.arg.libcallThreadContext);
+ ctx.sym.stackPointer = createGlobalVariable(
+ stack_pointer_name, !ctx.arg.getLibcallThreadContext());
}
if (ctx.arg.isMultithreaded()) {
// TLS symbols are all hidden/dso-local
auto tls_base_name =
- ctx.arg.libcallThreadContext ? "__init_tls_base" : "__tls_base";
+ ctx.arg.getLibcallThreadContext() ? "__init_tls_base" : "__tls_base";
ctx.sym.tlsBase = createGlobalVariable(tls_base_name, true,
WASM_SYMBOL_VISIBILITY_HIDDEN);
ctx.sym.tlsSize = createGlobalVariable("__tls_size", false,
@@ -961,7 +964,7 @@ static void createSyntheticSymbols() {
"__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN,
make<SyntheticFunction>(is64 ? i64ArgSignature : i32ArgSignature,
"__wasm_init_tls"));
- if (ctx.arg.libcallThreadContext) {
+ if (ctx.arg.getLibcallThreadContext()) {
ctx.sym.tlsBase->markLive();
ctx.sym.tlsSize->markLive();
ctx.sym.tlsAlign->markLive();
@@ -986,7 +989,7 @@ static void createOptionalSymbols() {
auto addDataLayoutSymbol = [&](StringRef s) -> DefinedData * {
// Data layout symbols are either defined by lld, or (in the case
// of PIC code) defined by the dynamic linker / embedder.
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
ctx.arg.allowUndefinedSymbols.insert(s);
return nullptr;
} else {
@@ -1005,7 +1008,7 @@ static void createOptionalSymbols() {
// for pic, __memory_base and __table_base are handled in
// createSyntheticSymbols.
- if (!ctx.isPic) {
+ if (!ctx.getIsPic()) {
ctx.sym.memoryBase = createOptionalGlobal("__memory_base", false);
ctx.sym.tableBase = createOptionalGlobal("__table_base", false);
}
@@ -1481,7 +1484,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
sym->forceExport = true;
}
- if (!ctx.arg.relocatable && !ctx.isPic) {
+ if (!ctx.arg.relocatable && !ctx.getIsPic()) {
// Add synthetic dummies for weak undefined functions. Must happen
// after LTO otherwise functions may not yet have signatures.
symtab->handleWeakUndefines();
diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 605d49f08fde7..ccebb059cf9a4 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -421,7 +421,7 @@ uint64_t InputChunk::getVA(uint64_t offset) const {
// their VA is that relative offset. In single-threaded builds TLS is instead
// lowered to normal data with a fixed base and so is assigned addresses as
// usual.
- if (ctx.isPic && ctx.arg.isMultithreaded() && isTLS())
+ if (ctx.getIsPic() && ctx.arg.isMultithreaded() && isTLS())
return getChunkOffset(offset);
return (outputSeg ? outputSeg->startVA : 0) + getChunkOffset(offset);
}
@@ -452,7 +452,7 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
Symbol *sym = file->getSymbol(rel);
// Runtime relocations are needed when we don't know the address of
// a symbol statically.
- bool requiresRuntimeReloc = ctx.isPic || sym->hasGOTIndex();
+ bool requiresRuntimeReloc = ctx.getIsPic() || sym->hasGOTIndex();
if (!requiresRuntimeReloc)
continue;
@@ -471,7 +471,7 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
writePtrConst(os, offset, is64, "offset");
// In PIC mode we need to add the __memory_base
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
if (isTLS())
writeUleb128(os, ctx.sym.tlsBase->getGlobalIndex(), "tls_base");
@@ -495,7 +495,7 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
writeU8(os, opcode_reloc_add, "ADD");
}
} else {
- assert(ctx.isPic);
+ assert(ctx.getIsPic());
const GlobalSymbol *baseSymbol = ctx.sym.memoryBase;
if (rel.Type == R_WASM_TABLE_INDEX_I32 ||
rel.Type == R_WASM_TABLE_INDEX_I64)
diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index 9c519a9c3dbe9..e02781225e27d 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -118,7 +118,7 @@ class InputChunk {
InputChunk(ObjFile *f, Kind k, StringRef name, uint32_t alignment = 0,
uint32_t flags = 0)
: name(name), file(f), alignment(alignment), flags(flags), sectionKind(k),
- live(!ctx.arg.gcSections), discarded(false) {}
+ live(!ctx.arg.getGcSections()), discarded(false) {}
ArrayRef<uint8_t> data() const { return rawData; }
uint64_t getTombstone() const;
@@ -162,7 +162,8 @@ class SyntheticMergedChunk;
// be found by looking at the next one).
struct SectionPiece {
SectionPiece(size_t off, uint32_t hash, bool live)
- : inputOff(off), live(live || !ctx.arg.gcSections), hash(hash >> 1) {}
+ : inputOff(off), live(live || !ctx.arg.getGcSections()), hash(hash >> 1) {
+ }
uint32_t inputOff;
uint32_t live : 1;
diff --git a/lld/wasm/InputElement.h b/lld/wasm/InputElement.h
index c2a24c8ff5f4e..029932fa61d9b 100644
--- a/lld/wasm/InputElement.h
+++ b/lld/wasm/InputElement.h
@@ -24,7 +24,7 @@ namespace wasm {
class InputElement {
protected:
InputElement(StringRef name, ObjFile *f)
- : file(f), live(!ctx.arg.gcSections), name(name) {}
+ : file(f), live(!ctx.arg.getGcSections()), name(name) {}
public:
StringRef getName() const { return name; }
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index c72f3102aaec3..0d641b93bc486 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -360,7 +360,7 @@ void ObjFile::addLegacyIndirectFunctionTableIfNeeded(
// We assume that this compilation unit has unrelocatable references to
// this table.
- ctx.legacyFunctionTable = true;
+ ctx.setLegacyFunctionTable(true);
}
static bool shouldMerge(const WasmSection &sec) {
diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h
index fd7fcb13f4426..a27462ad8dc44 100644
--- a/lld/wasm/InputFiles.h
+++ b/lld/wasm/InputFiles.h
@@ -73,7 +73,7 @@ class InputFile {
protected:
InputFile(Kind k, MemoryBufferRef m)
- : mb(m), fileKind(k), live(!ctx.arg.gcSections) {}
+ : mb(m), fileKind(k), live(!ctx.arg.getGcSections()) {}
void checkArch(llvm::Triple::ArchType arch) const;
diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp
index 1f82780e65a56..33ecafb44228f 100644
--- a/lld/wasm/LTO.cpp
+++ b/lld/wasm/LTO.cpp
@@ -67,14 +67,14 @@ static lto::Config createConfig() {
}
c.CGOptLevel = ctx.arg.ltoCgo;
- c.DebugPassManager = ctx.arg.ltoDebugPassManager;
+ c.DebugPassManager = ctx.arg.getLtoDebugPassManager();
c.AlwaysEmitRegularLTOObj = !ctx.arg.ltoObjPath.empty();
if (auto relocModel = getRelocModelFromCMModel())
c.RelocModel = *relocModel;
else if (ctx.arg.relocatable)
c.RelocModel = std::nullopt;
- else if (ctx.isPic)
+ else if (ctx.getIsPic())
c.RelocModel = Reloc::PIC_;
else if (ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic)
// With ImportDynamic we also need to use the PIC relocation model so that
diff --git a/lld/wasm/MarkLive.cpp b/lld/wasm/MarkLive.cpp
index 3364be006ca24..0321d88969c56 100644
--- a/lld/wasm/MarkLive.cpp
+++ b/lld/wasm/MarkLive.cpp
@@ -180,7 +180,7 @@ void MarkLive::mark() {
}
void markLive() {
- if (!ctx.arg.gcSections)
+ if (!ctx.arg.getGcSections())
return;
LLVM_DEBUG(dbgs() << "markLive\n");
@@ -226,7 +226,7 @@ bool MarkLive::isCallCtorsLive() {
// In Emscripten-style PIC, we call `__wasm_call_ctors` which calls
// `__wasm_apply_data_relocs`.
- if (ctx.isPic)
+ if (ctx.getIsPic())
return true;
// If there are any init functions, mark `__wasm_call_ctors` live so that
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index d9017fefffdd1..d28bc89e8e40f 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -108,7 +108,7 @@ void DataSection::finalizeContents() {
});
#endif
- assert((!ctx.isPic || ctx.arg.extendedConst || activeCount <= 1) &&
+ assert((!ctx.getIsPic() || ctx.arg.getExtendedConst() || activeCount <= 1) &&
"output segments should have been combined by now");
writeUleb128(os, segmentCount, "data segment count");
@@ -123,7 +123,7 @@ void DataSection::finalizeContents() {
if (segment->initFlags & WASM_DATA_SEGMENT_HAS_MEMINDEX)
writeUleb128(os, 0, "memory index");
if (segment->isActive()) {
- if (ctx.isPic && ctx.arg.extendedConst) {
+ if (ctx.getIsPic() && ctx.arg.getExtendedConst()) {
writeU8(os, WASM_OPCODE_GLOBAL_GET, "global get");
writeUleb128(os, ctx.sym.memoryBase->getGlobalIndex(),
"literal (global index)");
@@ -135,7 +135,7 @@ void DataSection::finalizeContents() {
} else {
WasmInitExpr initExpr;
initExpr.Extended = false;
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
assert(segment->startVA == 0);
initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET;
initExpr.Inst.Value.Global = ctx.sym.memoryBase->getGlobalIndex();
diff --git a/lld/wasm/OutputSegment.h b/lld/wasm/OutputSegment.h
index 05fcbacdf317b..c4f8915e14e07 100644
--- a/lld/wasm/OutputSegment.h
+++ b/lld/wasm/OutputSegment.h
@@ -28,7 +28,7 @@ class OutputSegment {
// to the output binary. However if the memory is imported, and
// we can't use memory.fill during startup (due to lack of bulk
// memory feature) then we include BSS segments verbatim.
- bool requiredInBinary() const { return !isBss || ctx.emitBssSegments; }
+ bool requiredInBinary() const { return !isBss || ctx.getEmitBssSegments(); }
bool isTLS() const { return name == ".tdata"; }
diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp
index cb597fdeffcf3..b6f2660d9ac5a 100644
--- a/lld/wasm/Relocations.cpp
+++ b/lld/wasm/Relocations.cpp
@@ -21,7 +21,7 @@ namespace lld::wasm {
static bool requiresGOTAccess(const Symbol *sym) {
if (sym->isShared())
return true;
- if (!ctx.isPic &&
+ if (!ctx.getIsPic() &&
ctx.arg.unresolvedSymbols != UnresolvedPolicy::ImportDynamic)
return false;
if (sym->isHidden() || sym->isLocal())
@@ -144,7 +144,7 @@ void scanRelocations(InputChunk *chunk) {
break;
}
- if (ctx.isPic || sym->isShared() ||
+ if (ctx.getIsPic() || sym->isShared() ||
(sym->isUndefined() &&
ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic)) {
switch (reloc.Type) {
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index ec6a0d957ce62..a0db9c613dbfc 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -148,7 +148,7 @@ std::pair<Symbol *, bool> SymbolTable::insertName(StringRef name) {
sym->canInline = true;
sym->traced = trace;
sym->forceExport = false;
- sym->referenced = !ctx.arg.gcSections;
+ sym->referenced = !ctx.arg.getGcSections();
symVector.emplace_back(sym);
return {sym, true};
}
@@ -934,12 +934,12 @@ TableSymbol *SymbolTable::createUndefinedIndirectFunctionTable(StringRef name) {
WasmTableType *type = make<WasmTableType>();
type->ElemType = ValType::FUNCREF;
type->Limits = limits;
- uint32_t flags = ctx.arg.exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
+ uint32_t flags = ctx.arg.getExportTable() ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
flags |= WASM_SYMBOL_UNDEFINED;
Symbol *sym =
addUndefinedTable(name, name, defaultModule, flags, nullptr, type);
sym->markLive();
- sym->forceExport = ctx.arg.exportTable;
+ sym->forceExport = ctx.arg.getExportTable();
return cast<TableSymbol>(sym);
}
@@ -950,10 +950,10 @@ TableSymbol *SymbolTable::createDefinedIndirectFunctionTable(StringRef name) {
WasmTableType type{ValType::FUNCREF, limits};
WasmTable desc{invalidIndex, type, name};
InputTable *table = make<InputTable>(desc, nullptr);
- uint32_t flags = ctx.arg.exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
+ uint32_t flags = ctx.arg.getExportTable() ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
TableSymbol *sym = addSyntheticTable(name, flags, table);
sym->markLive();
- sym->forceExport = ctx.arg.exportTable;
+ sym->forceExport = ctx.arg.getExportTable();
return sym;
}
@@ -985,7 +985,7 @@ TableSymbol *SymbolTable::resolveIndirectFunctionTable(bool required) {
}
if (required)
return createUndefinedIndirectFunctionTable(functionTableName);
- } else if ((existing && existing->isLive()) || ctx.arg.exportTable ||
+ } else if ((existing && existing->isLive()) || ctx.arg.getExportTable() ||
required) {
// A defined table is required. Either because the user request an exported
// table or because the table symbol is already live. The existing table is
diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp
index 26fff7c802eba..536f8e9c5ad6d 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -217,7 +217,7 @@ bool Symbol::isExported() const {
if (ctx.arg.shared && isLive() && isWeak() && !isHidden())
return true;
- if (ctx.arg.exportAll || (ctx.arg.exportDynamic && !isHidden()))
+ if (ctx.arg.exportAll || (ctx.arg.getExportDynamic() && !isHidden()))
return true;
return isExportedExplicit();
diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index 1e5c85bd94954..723b411299e14 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -143,10 +143,10 @@ class Symbol {
protected:
Symbol(StringRef name, Kind k, uint32_t flags, InputFile *f)
- : name(name), file(f), symbolKind(k), referenced(!ctx.arg.gcSections),
- requiresGOT(false), isUsedInRegularObj(false), forceExport(false),
- forceImport(false), canInline(false), traced(false), isStub(false),
- flags(flags) {}
+ : name(name), file(f), symbolKind(k),
+ referenced(!ctx.arg.getGcSections()), requiresGOT(false),
+ isUsedInRegularObj(false), forceExport(false), forceImport(false),
+ canInline(false), traced(false), isStub(false), flags(flags) {}
StringRef name;
InputFile *file;
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index c629ed3cf2bb4..619b31990499d 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -53,7 +53,7 @@ class SubSection {
};
void writeGetTLSBase(const Ctx &ctx, raw_ostream &os) {
- if (ctx.arg.libcallThreadContext) {
+ if (ctx.arg.getLibcallThreadContext()) {
writeU8(os, WASM_OPCODE_CALL, "call");
writeUleb128(os, ctx.sym.getTLSBase->getFunctionIndex(), "function index");
} else {
@@ -65,7 +65,7 @@ void writeGetTLSBase(const Ctx &ctx, raw_ostream &os) {
} // namespace
bool DylinkSection::isNeeded() const {
- return ctx.isPic ||
+ return ctx.getIsPic() ||
ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic ||
!ctx.sharedFiles.empty();
}
@@ -199,7 +199,7 @@ void ImportSection::addGOTEntry(Symbol *sym) {
return;
LLVM_DEBUG(dbgs() << "addGOTEntry: " << toString(*sym) << "\n");
sym->setGOTIndex(numImportedGlobals++);
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
// Any symbol that is assigned an normal GOT entry must be exported
// otherwise the dynamic linker won't be able create the entry that contains
// it.
@@ -380,7 +380,7 @@ void TableSection::addTable(InputTable *table) {
return;
// Some inputs require that the indirect function table be assigned to table
// number 0.
- if (ctx.legacyFunctionTable &&
+ if (ctx.getLegacyFunctionTable() &&
isa<DefinedTable>(ctx.sym.indirectFunctionTable) &&
cast<DefinedTable>(ctx.sym.indirectFunctionTable)->table == table) {
if (out.importSec->getNumImportedTables()) {
@@ -481,7 +481,7 @@ void GlobalSection::addInternalGOTEntry(Symbol *sym) {
}
void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const {
- assert(!ctx.arg.extendedConst || TLS);
+ assert(!ctx.arg.getExtendedConst() || TLS);
bool is64 = ctx.arg.is64.value_or(false);
unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD;
@@ -535,7 +535,7 @@ void GlobalSection::writeBody() {
// In the case of dynamic linking, unless we have 'extended-const'
// available, these global must to be mutable since they get updated to
// the correct runtime value during `__wasm_apply_global_relocs`.
- if (!ctx.arg.extendedConst && ctx.isPic && !sym->isTLS())
+ if (!ctx.arg.getExtendedConst() && ctx.getIsPic() && !sym->isTLS())
mutable_ = true;
// With multi-threading any TLS globals must be mutable since they get
// set during `__wasm_apply_global_tls_relocs`
@@ -548,7 +548,7 @@ void GlobalSection::writeBody() {
bool useExtendedConst = false;
uint32_t globalIdx;
int64_t offset;
- if (ctx.arg.extendedConst && ctx.isPic) {
+ if (ctx.arg.getExtendedConst() && ctx.getIsPic()) {
if (auto *d = dyn_cast<DefinedData>(sym)) {
if (!sym->isTLS()) {
globalIdx = ctx.sym.memoryBase->getGlobalIndex();
@@ -644,7 +644,7 @@ void ElemSection::writeBody() {
WasmInitExpr initExpr;
initExpr.Extended = false;
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET;
initExpr.Inst.Value.Global = ctx.sym.tableBase->getGlobalIndex();
} else {
diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h
index e0bd91a739026..838817dd99e49 100644
--- a/lld/wasm/SyntheticSections.h
+++ b/lld/wasm/SyntheticSections.h
@@ -269,7 +269,7 @@ class GlobalSection : public SyntheticSection {
// transform a `global.get` to an `i32.const`.
void addInternalGOTEntry(Symbol *sym);
bool needsRelocations() {
- if (ctx.arg.extendedConst)
+ if (ctx.arg.getExtendedConst())
return false;
return llvm::any_of(internalGotSymbols,
[=](Symbol *sym) { return !sym->isTLS(); });
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 7ed266a06ca8c..7b79a5ac8b9a4 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -127,7 +127,7 @@ class Writer {
};
void writeSetTLSBase(const Ctx &ctx, raw_ostream &os) {
- if (ctx.arg.libcallThreadContext) {
+ if (ctx.arg.getLibcallThreadContext()) {
writeU8(os, WASM_OPCODE_CALL, "call");
writeUleb128(os, ctx.sym.setTLSBase->getFunctionIndex(), "function index");
} else {
@@ -351,7 +351,7 @@ void Writer::layoutMemory() {
uint64_t memoryPtr = 0;
auto placeStack = [&]() {
- if (ctx.arg.relocatable || ctx.isPic)
+ if (ctx.arg.relocatable || ctx.getIsPic())
return;
memoryPtr = alignTo(memoryPtr, stackAlignment);
if (ctx.sym.stackLow)
@@ -447,7 +447,7 @@ void Writer::layoutMemory() {
uint64_t staticDataSize = memoryPtr - dataStart;
log("mem: static data = " + Twine(staticDataSize));
- if (ctx.isPic)
+ if (ctx.getIsPic())
out.dylinkSec->memSize = staticDataSize;
if (!ctx.arg.stackFirst)
@@ -513,14 +513,14 @@ void Writer::layoutMemory() {
Twine(maxMemorySetting));
maxMemory = ctx.arg.maxMemory;
- } else if (ctx.arg.noGrowableMemory) {
+ } else if (ctx.arg.getNoGrowableMemory()) {
maxMemory = memoryPtr;
}
// If no maxMemory config was supplied but we are building with
// shared memory, we need to pick a sensible upper limit.
if (ctx.arg.sharedMemory && maxMemory == 0) {
- if (ctx.isPic)
+ if (ctx.getIsPic())
maxMemory = maxMemorySetting;
else
maxMemory = memoryPtr;
@@ -600,7 +600,7 @@ void Writer::populateTargetFeatures() {
SmallSet<std::string, 8> &allowed = out.targetFeaturesSec->features;
bool tlsUsed = false;
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
// This should not be necessary because all PIC objects should
// contain the `mutable-globals` feature.
// TODO (https://github.com/llvm/llvm-project/issues/51681)
@@ -646,7 +646,7 @@ void Writer::populateTargetFeatures() {
tlsUsed = tlsUsed || llvm::any_of(file->segments, isTLS);
// Ensure that we're not mixing incompatible thread context models
- if (ctx.arg.libcallThreadContext &&
+ if (ctx.arg.getLibcallThreadContext() &&
llvm::any_of(file->getSymbols(), [](const auto &sym) {
return sym && sym->getName() == "__stack_pointer" &&
sym->kind() == Symbol::UndefinedGlobalKind &&
@@ -679,7 +679,7 @@ void Writer::populateTargetFeatures() {
if (!allowed.contains("bulk-memory"))
error("'bulk-memory' feature must be used in order to use thread-local "
"storage");
- if (!allowed.contains("atomics") && !ctx.arg.cooperativeThreading)
+ if (!allowed.contains("atomics") && !ctx.arg.getCooperativeThreading())
error("'atomics' feature must be used in order to use thread-local "
"storage");
}
@@ -717,10 +717,10 @@ void Writer::populateTargetFeatures() {
// the bss segments, so these segments need to exist in the binary.
if (ctx.arg.emitRelocs ||
(ctx.arg.memoryImport.has_value() && !allowed.contains("bulk-memory")))
- ctx.emitBssSegments = true;
+ ctx.setEmitBssSegments(true);
if (allowed.contains("extended-const"))
- ctx.arg.extendedConst = true;
+ ctx.arg.setExtendedConst(true);
for (auto &feature : allowed)
log("Allowed feature: " + feature);
@@ -772,18 +772,18 @@ static bool shouldImport(Symbol *sym) {
return true;
if (!sym->isUndefined())
return false;
- if (sym->isWeak() && !ctx.arg.relocatable && !ctx.isPic)
+ if (sym->isWeak() && !ctx.arg.relocatable && !ctx.getIsPic())
return false;
// In PIC mode we only need to import functions when they are called directly.
// Indirect usage all goes via GOT imports.
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
if (auto *f = dyn_cast<UndefinedFunction>(sym))
if (!f->isCalledDirectly)
return false;
}
- if (ctx.isPic || ctx.arg.relocatable || ctx.arg.importUndefined ||
+ if (ctx.getIsPic() || ctx.arg.relocatable || ctx.arg.importUndefined ||
ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic)
return true;
if (ctx.arg.allowUndefinedSymbols.contains(sym->getName()))
@@ -917,7 +917,7 @@ void Writer::calculateTypes() {
// which calls the constructors and destructors.
void Writer::createCommandExportWrappers() {
// This logic doesn't currently support Emscripten-style PIC mode.
- assert(!ctx.isPic);
+ assert(!ctx.getIsPic());
// If there are no ctors and there's no libc `__wasm_call_dtors` to
// call, don't wrap the exports.
@@ -975,7 +975,8 @@ static void finalizeIndirectFunctionTable() {
uint32_t tableSize = ctx.arg.tableBase + out.elemSec->numEntries();
WasmLimits limits = {0, tableSize, 0, 0};
- if (ctx.sym.indirectFunctionTable->isDefined() && !ctx.arg.growableTable) {
+ if (ctx.sym.indirectFunctionTable->isDefined() &&
+ !ctx.arg.getGrowableTable()) {
limits.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
limits.Maximum = limits.Minimum;
}
@@ -1065,7 +1066,7 @@ OutputSegment *Writer::createOutputSegment(StringRef name) {
// be able to run TLS initialization on spawned threads, so that's managed
// here by flagging TLS as passive as well.
bool needsPassiveInit =
- ctx.arg.sharedMemory || (ctx.arg.cooperativeThreading && s->isTLS());
+ ctx.arg.sharedMemory || (ctx.arg.getCooperativeThreading() && s->isTLS());
if (needsPassiveInit)
s->initFlags = WASM_DATA_SEGMENT_IS_PASSIVE;
if (!ctx.arg.relocatable && name.starts_with(".bss"))
@@ -1198,8 +1199,8 @@ void Writer::combineActiveOutputSegments() {
// combines all active data segments into a single .data segment.
// This restriction does not apply when the extended const extension is
// available: https://github.com/WebAssembly/extended-const
- assert(!ctx.arg.extendedConst);
- assert(ctx.isPic);
+ assert(!ctx.arg.getExtendedConst());
+ assert(ctx.getIsPic());
auto isActive = [](const OutputSegment *s) {
return s->requiredInBinary() && s->isActive();
};
@@ -1318,7 +1319,7 @@ void Writer::createSyntheticInitFunctions() {
}
}
- if (ctx.isPic && out.globalSec->needsRelocations()) {
+ if (ctx.getIsPic() && out.globalSec->needsRelocations()) {
ctx.sym.applyGlobalRelocs = symtab->addSyntheticFunction(
"__wasm_apply_global_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN,
make<SyntheticFunction>(nullSignature, "__wasm_apply_global_relocs"));
@@ -1409,10 +1410,10 @@ void Writer::createInitMemoryFunction() {
unsigned numAddressLocals = 0;
unsigned tlsAddressLocal = -1;
unsigned flagAddressLocal = -1;
- if (ctx.isPic && ctx.arg.sharedMemory)
+ if (ctx.getIsPic() && ctx.arg.sharedMemory)
flagAddressLocal = numAddressLocals++;
bool needsTLSAddressLocal =
- ctx.isPic && ctx.arg.isMultithreaded() &&
+ ctx.getIsPic() && ctx.arg.isMultithreaded() &&
llvm::any_of(segments, [this](const OutputSegment *s) {
return s->isTLS() && needsPassiveInitialization(s);
});
@@ -1425,7 +1426,7 @@ void Writer::createInitMemoryFunction() {
}
auto writeGetFlagAddress = [&]() {
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
writeU8(os, WASM_OPCODE_LOCAL_GET, "local.get");
writeUleb128(os, flagAddressLocal, "flag address local index");
} else {
@@ -1435,7 +1436,7 @@ void Writer::createInitMemoryFunction() {
if (ctx.arg.sharedMemory) {
// With PIC code we cache the flag address in a local.
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
writeUleb128(os, ctx.sym.memoryBase->getGlobalIndex(), "memory_base");
writePtrConst(os, flagAddress, is64, "flag address");
@@ -1478,7 +1479,7 @@ void Writer::createInitMemoryFunction() {
// instructions take as their first argument the destination
// address.
writePtrConst(os, s->startVA, is64, "destination address");
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
writeUleb128(os, ctx.sym.memoryBase->getGlobalIndex(),
"__memory_base");
@@ -1497,11 +1498,11 @@ void Writer::createInitMemoryFunction() {
// here. For PIC builds the result of the address computation above is
// what's stored into the global.
if (ctx.arg.isMultithreaded() && s->isTLS()) {
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
// Cache the result of the addition in the TLS address local
writeU8(os, WASM_OPCODE_LOCAL_TEE, "local.tee");
writeUleb128(os, tlsAddressLocal, "tls address local");
- if (ctx.arg.libcallThreadContext) {
+ if (ctx.arg.getLibcallThreadContext()) {
writeU8(os, WASM_OPCODE_LOCAL_GET, "local.get");
writeUleb128(os, tlsAddressLocal, "tls address local");
writeU8(os, WASM_OPCODE_GLOBAL_SET, "global.set");
@@ -1510,11 +1511,11 @@ void Writer::createInitMemoryFunction() {
}
} else {
writePtrConst(os, s->startVA, is64, "destination address");
- if (ctx.arg.libcallThreadContext)
+ if (ctx.arg.getLibcallThreadContext())
ctx.sym.tlsBase->global->setPointerValue(s->startVA);
}
writeSetTLSBase(ctx, os);
- if (ctx.isPic) {
+ if (ctx.getIsPic()) {
writeU8(os, WASM_OPCODE_LOCAL_GET, "local.get");
writeUleb128(os, tlsAddressLocal, "tls address local");
}
@@ -1874,7 +1875,7 @@ void Writer::createSyntheticSectionsPostLayout() {
void Writer::run() {
// For PIC code the table base is assigned dynamically by the loader.
// For non-PIC, we start at 1 so that accessing table index 0 always traps.
- if (!ctx.isPic && ctx.sym.tableBase)
+ if (!ctx.getIsPic() && ctx.sym.tableBase)
setGlobalPtr(cast<DefinedGlobal>(ctx.sym.tableBase), ctx.arg.tableBase);
log("-- allocateCommonSymbols");
@@ -1919,7 +1920,7 @@ void Writer::run() {
// `__memory_base` import. Unless we support the extended const expression we
// can't do addition inside the constant expression, so we much combine the
// segments into a single one that can live at `__memory_base`.
- if (ctx.isPic && !ctx.arg.extendedConst) {
+ if (ctx.getIsPic() && !ctx.arg.getExtendedConst()) {
log("-- combineActiveOutputSegments");
combineActiveOutputSegments();
}
@@ -1964,7 +1965,7 @@ void Writer::run() {
// If the input contains a call to `__wasm_call_ctors`, either in one of
// the input objects or an explicit export from the command-line, we
// assume ctors and dtors are taken care of already.
- if (!ctx.arg.relocatable && !ctx.isPic &&
+ if (!ctx.arg.relocatable && !ctx.getIsPic() &&
!ctx.sym.callCtors->isUsedInRegularObj &&
!ctx.sym.callCtors->isExported()) {
log("-- createCommandExportWrappers");
diff --git a/lldb/include/lldb/Core/FormatEntity.h b/lldb/include/lldb/Core/FormatEntity.h
index f0e781c718765..9f7c417727366 100644
--- a/lldb/include/lldb/Core/FormatEntity.h
+++ b/lldb/include/lldb/Core/FormatEntity.h
@@ -13,6 +13,7 @@
#include "lldb/lldb-types.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
@@ -187,7 +188,7 @@ struct Entry {
fmt = lldb::eFormatDefault;
number = 0;
level = 0;
- deref = false;
+ setDeref(false);
}
static const char *TypeToCString(Type t);
@@ -199,13 +200,16 @@ struct Entry {
return false;
if (printf_format != rhs.printf_format)
return false;
- if (children_stack != rhs.children_stack)
+ if ((llvm::ArrayRef<std::vector<lldb_private::FormatEntity::Entry>>(
+ children_stack) !=
+ llvm::ArrayRef<std::vector<lldb_private::FormatEntity::Entry>>(
+ rhs.children_stack)))
return false;
if (type != rhs.type)
return false;
if (fmt != rhs.fmt)
return false;
- if (deref != rhs.deref)
+ if (getDeref() != rhs.getDeref())
return false;
return true;
}
@@ -220,14 +224,15 @@ struct Entry {
/// A stack of children entries, used by Scope entries to provide alterantive
/// children. All other entries have a stack of size 1.
/// @{
- llvm::SmallVector<std::vector<Entry>, 1> children_stack;
+ llvm::SmallVectorWithFlags<std::vector<Entry>, 1> children_stack;
size_t level = 0;
/// @}
Type type = Type::Invalid;
lldb::Format fmt = lldb::eFormatDefault;
lldb::addr_t number = 0;
- bool deref = false;
+ bool getDeref() const { return children_stack.getFlag(0); }
+ void setDeref(bool Value) { children_stack.setFlag(0, Value); }
};
class Formatter {
@@ -235,8 +240,8 @@ class Formatter {
Formatter(const SymbolContext *sc, const ExecutionContext *exe_ctx,
const Address *addr, bool function_changed, bool initial_function)
: m_sc(sc), m_exe_ctx(exe_ctx), m_addr(addr),
- m_function_changed(function_changed),
- m_initial_function(initial_function) {}
+ m_entry_type_stack(decltype(this->m_entry_type_stack)::withFlags(
+ unsigned(function_changed) | (unsigned(initial_function) << 1))) {}
bool Format(const Entry &entry, Stream &s, ValueObject *valobj = nullptr);
@@ -269,10 +274,10 @@ class Formatter {
const SymbolContext *const m_sc = nullptr;
const ExecutionContext *const m_exe_ctx = nullptr;
const Address *const m_addr = nullptr;
- const bool m_function_changed = false;
- const bool m_initial_function = false;
+ bool getM_function_changed() const { return m_entry_type_stack.getFlag(0); }
+ bool getM_initial_function() const { return m_entry_type_stack.getFlag(1); }
- llvm::SmallVector<Entry::Type, 1> m_entry_type_stack;
+ llvm::SmallVectorWithFlags<Entry::Type, 1, 2> m_entry_type_stack;
};
Status Parse(const llvm::StringRef &format, Entry &entry);
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 52b3683b2570f..354934abb517f 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -379,7 +379,7 @@ VariableAnnotator::AnnotateStructured(Instruction &inst) {
llvm::DIDumpOptions opts;
opts.ShowAddresses = false;
// Prefer "register-only" output when we have an ABI.
- opts.PrintRegisterOnly = static_cast<bool>(abi_sp);
+ opts.setPrintRegisterOnly(static_cast<bool>(abi_sp));
llvm::DenseMap<lldb::user_id_t, VariableAnnotation> current_vars;
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index b911c4c55379a..8c8cea11e4072 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -435,7 +435,7 @@ void FormatEntity::Entry::Dump(Stream &s, int depth) const {
s.Printf("printf_format = \"%s\"", printf_format.c_str());
if (number != 0)
s.Printf("number = %" PRIu64 " (0x%" PRIx64 "), ", number, number);
- if (deref)
+ if (getDeref())
s.PutCString("deref = true, ");
s.EOL();
for (const auto &children : children_stack) {
@@ -766,7 +766,7 @@ bool FormatEntity::Formatter::DumpValue(Stream &s,
? ValueObject::eValueObjectRepresentationStyleValue
: ValueObject::eValueObjectRepresentationStyleSummary;
- bool do_deref_pointer = entry.deref;
+ bool do_deref_pointer = entry.getDeref();
bool is_script = false;
switch (entry.type) {
case FormatEntity::Entry::Type::ScriptVariable:
@@ -1798,10 +1798,10 @@ bool FormatEntity::Formatter::Format(const Entry &entry, Stream &s,
return false;
case Entry::Type::FunctionDidChange:
- return m_function_changed;
+ return getM_function_changed();
case Entry::Type::FunctionInitialFunction:
- return m_initial_function;
+ return getM_initial_function();
case Entry::Type::FunctionName: {
if (m_sc) {
@@ -1985,7 +1985,7 @@ bool FormatEntity::Formatter::Format(const Entry &entry, Stream &s,
return false;
case Entry::Type::FunctionChanged:
- return m_function_changed;
+ return getM_function_changed();
case Entry::Type::FunctionIsOptimized: {
bool is_optimized = false;
@@ -2000,7 +2000,7 @@ bool FormatEntity::Formatter::Format(const Entry &entry, Stream &s,
}
case Entry::Type::FunctionInitial:
- return m_initial_function;
+ return getM_initial_function();
case Entry::Type::LineEntryFile:
if (m_sc && m_sc->line_entry.IsValid()) {
@@ -2466,7 +2466,7 @@ static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry,
// Check for dereferences
if (variable[0] == '*') {
- entry.deref = true;
+ entry.setDeref(true);
variable = variable.drop_front();
}
@@ -2507,7 +2507,7 @@ static Status ParseInternal(llvm::StringRef &format, Entry &parent_entry,
default:
// Make sure someone didn't try to dereference anything but ${var}
// or ${svar}
- if (entry.deref) {
+ if (entry.getDeref()) {
error = Status::FromErrorStringWithFormat(
"${%s} can't be dereferenced, only ${var} and ${svar} can.",
variable.str().c_str());
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index 9d6dd2617a945..ac05b8fa94a4d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -1273,8 +1273,8 @@ RemapModule(OptionalClangModuleID from_id,
OptionalClangModuleID parent = RemapModule(
from_source.GetIDForModule(module->Parent), from_source, to_source);
TypeSystemClang &to_ts = to_source.GetTypeSystem();
- return to_ts.GetOrCreateClangModule(module->Name, parent, module->IsFramework,
- module->IsExplicit);
+ return to_ts.GetOrCreateClangModule(
+ module->Name, parent, module->getIsFramework(), module->getIsExplicit());
}
void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index fb8784ed8919c..8d1903afe728f 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -300,9 +300,9 @@ static std::string GetXcodeSDKDir(std::string preferred,
}
llvm::StringRef PlatformAppleSimulator::GetSDKFilepath() {
- if (!m_have_searched_for_sdk) {
+ if (!getM_have_searched_for_sdk()) {
m_sdk = GetXcodeSDKDir(m_sdk_name_primary, m_sdk_name_secondary);
- m_have_searched_for_sdk = true;
+ setM_have_searched_for_sdk(true);
}
return m_sdk;
}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
index 9d0c1764e84a6..7a39df1b367c9 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
@@ -18,6 +18,7 @@
#include "lldb/Utility/XcodeSDK.h"
#include "lldb/lldb-forward.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/TargetParser/Triple.h"
@@ -116,10 +117,15 @@ class PlatformAppleSimulator : public PlatformDarwin {
llvm::StringRef GetSDKFilepath();
llvm::Triple::OSType m_os_type = llvm::Triple::UnknownOS;
- llvm::SmallVector<llvm::StringRef, 4> m_supported_triples = {};
+ llvm::SmallVectorWithFlags<llvm::StringRef, 4> m_supported_triples = {};
std::string m_sdk_name_primary;
std::string m_sdk_name_secondary;
- bool m_have_searched_for_sdk = false;
+ bool getM_have_searched_for_sdk() const {
+ return m_supported_triples.getFlag(0);
+ }
+ void setM_have_searched_for_sdk(bool Value) {
+ m_supported_triples.setFlag(0, Value);
+ }
std::string m_sdk;
XcodeSDK::Type m_sdk_type;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 21c37af2400f9..d7ab4bd9cd250 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -58,10 +58,10 @@ char SymbolFileDWARFDebugMap::ID;
const SymbolFileDWARFDebugMap::FileRangeMap &
SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
SymbolFileDWARFDebugMap *exe_symfile) {
- if (file_range_map_valid)
+ if (getFile_range_map_valid())
return file_range_map;
- file_range_map_valid = true;
+ setFile_range_map_valid(true);
Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this);
if (!oso_module)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 0946e7521874f..a21beb9ff151d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -12,6 +12,7 @@
#include "DIERef.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Utility/RangeMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Chrono.h"
#include <bitset>
#include <map>
@@ -178,7 +179,7 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {
Status oso_load_error;
OSOInfoSP oso_sp;
/// The compile units that an object file contains.
- llvm::SmallVector<lldb::CompUnitSP, 2> compile_units_sps;
+ llvm::SmallVectorWithFlags<lldb::CompUnitSP, 2> compile_units_sps;
/// A map from the compile unit ID to its index in the vector.
llvm::SmallDenseMap<uint64_t, uint64_t, 2> id_to_index_map;
uint32_t first_symbol_index = UINT32_MAX;
@@ -186,7 +187,12 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {
uint32_t first_symbol_id = UINT32_MAX;
uint32_t last_symbol_id = UINT32_MAX;
FileRangeMap file_range_map;
- bool file_range_map_valid = false;
+ bool getFile_range_map_valid() const {
+ return compile_units_sps.getFlag(0);
+ }
+ void setFile_range_map_valid(bool Value) {
+ compile_units_sps.setFlag(0, Value);
+ }
CompileUnitInfo() = default;
diff --git a/llvm/include/llvm/ADT/GenericUniformityImpl.h b/llvm/include/llvm/ADT/GenericUniformityImpl.h
index c6f0bba051b60..c8cefc76401ca 100644
--- a/llvm/include/llvm/ADT/GenericUniformityImpl.h
+++ b/llvm/include/llvm/ADT/GenericUniformityImpl.h
@@ -46,6 +46,7 @@
#define LLVM_ADT_GENERICUNIFORMITYIMPL_H
#include "llvm/ADT/GenericUniformityInfo.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
@@ -388,7 +389,7 @@ template <typename ContextT> class GenericUniformityAnalysisImpl {
/// and everything is uniform. Otherwise, values not in UniformValues
/// (e.g. newly created) are conservatively treated as divergent.
bool isDivergent(ConstValueRefT V) const {
- if (!HasBranchDivergence)
+ if (!TemporalDivergenceList.getFlag(0))
return false;
// Only values that were present during analysis are tracked in
// UniformValues (Instructions/Arguments for IR, Registers for MIR).
@@ -415,7 +416,9 @@ template <typename ContextT> class GenericUniformityAnalysisImpl {
/// IR specialization iterates F.args(); default is a no-op.
bool printDivergentArgs(raw_ostream &Out) const;
- SmallVector<TemporalDivergenceTuple, 8> TemporalDivergenceList;
+ // Flag 0 records whether the target has branch divergence. It is set at
+ // the start of compute(); until then, isDivergent() returns false.
+ SmallVectorWithFlags<TemporalDivergenceTuple, 8> TemporalDivergenceList;
void recordTemporalDivergence(ConstValueRefT, const InstructionT *, CycleRef);
@@ -432,11 +435,6 @@ template <typename ContextT> class GenericUniformityAnalysisImpl {
const CycleInfoT &CI;
const TargetTransformInfo *TTI = nullptr;
- // Whether the target has branch divergence. Set at the start of compute(),
- // which is only called when the target has branch divergence. When false,
- // isDivergent() returns false for all values.
- bool HasBranchDivergence = false;
-
SmallPtrSet<const BlockT *, 32> DivergentTermBlocks;
// Values known to be uniform. Populated in initialize() with all values,
@@ -1155,7 +1153,7 @@ void GenericUniformityAnalysisImpl<ContextT>::analyzeControlDivergence(
template <typename ContextT>
void GenericUniformityAnalysisImpl<ContextT>::compute() {
- HasBranchDivergence = true;
+ TemporalDivergenceList.setFlag(0, true);
// All values on the Worklist are divergent.
// Their users may not have been updated yet.
diff --git a/llvm/include/llvm/ADT/SmallVectorWithFlags.h b/llvm/include/llvm/ADT/SmallVectorWithFlags.h
index 5d10aa144c7d7..ad8aa62ecdb73 100644
--- a/llvm/include/llvm/ADT/SmallVectorWithFlags.h
+++ b/llvm/include/llvm/ADT/SmallVectorWithFlags.h
@@ -56,6 +56,20 @@ class SmallVectorWithFlagsImpl
setFlags(Value ? getFlags() | Mask : getFlags() & ~Mask);
}
+ using Base::assign;
+
+ /// Replace the elements with an ordinary vector, preserving this vector's
+ /// flags. Take over its heap buffer when the capacity fits in this header.
+ void assign(SmallVectorImpl<T> &&RHS) {
+ if (RHS.capacity() <= this->max_size()) {
+ this->moveAssignFrom(std::move(RHS));
+ } else {
+ Base::assign(std::make_move_iterator(RHS.begin()),
+ std::make_move_iterator(RHS.end()));
+ RHS.clear();
+ }
+ }
+
SmallVectorWithFlagsImpl(const SmallVectorWithFlagsImpl &) = delete;
SmallVectorWithFlagsImpl &operator=(const SmallVectorWithFlagsImpl &RHS) {
@@ -145,6 +159,14 @@ class LLVM_GSL_OWNER SmallVectorWithFlags
public:
SmallVectorWithFlags() : Base(N) {}
+ /// Construct a vector and set its complete flag mask.
+ template <typename... Args>
+ static SmallVectorWithFlags withFlags(unsigned Flags, Args &&...Arguments) {
+ SmallVectorWithFlags Result(std::forward<Args>(Arguments)...);
+ Result.setFlags(Flags);
+ return Result;
+ }
+
~SmallVectorWithFlags() { this->destroy_range(this->begin(), this->end()); }
explicit SmallVectorWithFlags(size_t Size) : Base(N) { this->resize(Size); }
@@ -185,6 +207,30 @@ class LLVM_GSL_OWNER SmallVectorWithFlags
this->setFlags(Flags);
}
+ /// Copy elements from an ordinary vector, starting with clear flags.
+ explicit SmallVectorWithFlags(const SmallVectorImpl<T> &RHS) : Base(N) {
+ this->append(RHS.begin(), RHS.end());
+ }
+
+ /// Move elements from an ordinary vector, starting with clear flags.
+ explicit SmallVectorWithFlags(SmallVectorImpl<T> &&RHS)
+ : SmallVectorWithFlags(0, std::move(RHS)) {}
+
+ /// Move elements from an ordinary vector and supply their flag mask.
+ SmallVectorWithFlags(unsigned Flags, SmallVectorImpl<T> &&RHS) : Base(N) {
+ if (!RHS.empty()) {
+ if (RHS.capacity() <= this->max_size()) {
+ this->moveConstructFrom(std::move(RHS));
+ } else {
+ // A plain vector can reserve more capacity than this header can hold.
+ this->append(std::make_move_iterator(RHS.begin()),
+ std::make_move_iterator(RHS.end()));
+ RHS.clear();
+ }
+ }
+ this->setFlags(Flags);
+ }
+
SmallVectorWithFlags(Base &&RHS) : Base(N) {
if (!RHS.empty()) {
// See SmallVector(SmallVectorImpl &&) for the rationale of this branch.
@@ -235,6 +281,21 @@ class LLVM_GSL_OWNER SmallVectorWithFlags
}
};
+namespace detail {
+template <typename Vector, unsigned FlagBits> struct SmallVectorWithFlagsType;
+
+template <typename T, unsigned N, unsigned FlagBits>
+struct SmallVectorWithFlagsType<SmallVector<T, N>, FlagBits> {
+ using type = SmallVectorWithFlags<T, N, FlagBits>;
+};
+} // namespace detail
+
+/// Preserve a SmallVector alias's element type and inline capacity while adding
+/// flags, including when the capacity is selected by the target's data layout.
+template <typename Vector, unsigned FlagBits = 1>
+using SmallVectorWithFlagsFor =
+ typename detail::SmallVectorWithFlagsType<Vector, FlagBits>::type;
+
/// Also covers complete containers, including across inline capacities.
template <typename T, unsigned FlagBits>
void swap(SmallVectorWithFlagsImpl<T, FlagBits> &LHS,
diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h
index b6cae7c1cba85..82176cb154add 100644
--- a/llvm/include/llvm/Analysis/AliasAnalysis.h
+++ b/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -39,6 +39,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/Function.h"
@@ -284,7 +285,8 @@ class AAQueryInfo {
/// 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;
+ // Flag bits 0 and 1 record cross-iteration queries and disabled DT queries.
+ SmallVectorWithFlags<AAQueryInfo::LocPair, 4, 2> AssumptionBasedResults;
/// Tracks whether the accesses may be on different cycle iterations.
///
@@ -300,11 +302,17 @@ class AAQueryInfo {
/// %addr2 = gep %alloca2, 0, (%l + 1)
/// alias(%p, %addr1) -> MayAlias !
/// store %l, ...
- bool MayBeCrossIteration = false;
+ bool mayBeCrossIteration() const { return AssumptionBasedResults.getFlag(0); }
+ void setMayBeCrossIteration(bool Value) {
+ AssumptionBasedResults.setFlag(0, Value);
+ }
/// Whether alias analysis is allowed to use the dominator tree, for use by
/// passes that lazily update the DT while performing AA queries.
- bool UseDominatorTree = true;
+ bool usesDominatorTree() const { return !AssumptionBasedResults.getFlag(1); }
+ void setUseDominatorTree(bool Value) {
+ AssumptionBasedResults.setFlag(1, !Value);
+ }
AAQueryInfo(AAResults &AAR, CaptureAnalysis *CA) : AAR(AAR), CA(CA) {}
};
@@ -661,12 +669,10 @@ class BatchAAResults {
}
/// Assume that values may come from different cycle iterations.
- void enableCrossIterationMode() {
- AAQI.MayBeCrossIteration = true;
- }
+ void enableCrossIterationMode() { AAQI.setMayBeCrossIteration(true); }
/// Disable the use of the dominator tree during alias analysis queries.
- void disableDominatorTree() { AAQI.UseDominatorTree = false; }
+ void disableDominatorTree() { AAQI.setUseDominatorTree(false); }
};
/// Temporarily set the cross iteration mode on a BatchAA instance.
@@ -676,11 +682,11 @@ class BatchAACrossIterationScope {
public:
BatchAACrossIterationScope(BatchAAResults &BAA, bool CrossIteration)
- : BAA(BAA), OrigCrossIteration(BAA.AAQI.MayBeCrossIteration) {
- BAA.AAQI.MayBeCrossIteration = CrossIteration;
+ : BAA(BAA), OrigCrossIteration(BAA.AAQI.mayBeCrossIteration()) {
+ BAA.AAQI.setMayBeCrossIteration(CrossIteration);
}
~BatchAACrossIterationScope() {
- BAA.AAQI.MayBeCrossIteration = OrigCrossIteration;
+ BAA.AAQI.setMayBeCrossIteration(OrigCrossIteration);
}
};
diff --git a/llvm/include/llvm/Analysis/AssumptionCache.h b/llvm/include/llvm/Analysis/AssumptionCache.h
index df955432e9360..1672368dec025 100644
--- a/llvm/include/llvm/Analysis/AssumptionCache.h
+++ b/llvm/include/llvm/Analysis/AssumptionCache.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
@@ -66,7 +67,8 @@ class AssumptionCache {
/// Vector of weak value handles to calls of the \@llvm.assume
/// intrinsic.
- SmallVector<WeakVH, 4> AssumeHandles;
+ // Flag bit 0 records whether the function has been scanned.
+ SmallVectorWithFlags<WeakVH, 4> AssumeHandles;
class LLVM_ABI AffectedValueCallbackVH final : public CallbackVH {
AssumptionCache *AC;
@@ -103,7 +105,7 @@ class AssumptionCache {
///
/// We want to be as lazy about this as possible, and so we scan the function
/// at the last moment.
- bool Scanned = false;
+ bool isScanned() const { return AssumeHandles.getFlag(0); }
/// Scan the function for assumptions and add them to the cache.
LLVM_ABI void scanFunction();
@@ -145,7 +147,7 @@ class AssumptionCache {
void clear() {
AssumeHandles.clear();
AffectedValues.clear();
- Scanned = false;
+ AssumeHandles.setFlag(0, false);
}
/// Access the list of assumption handles currently tracked for this
@@ -157,7 +159,7 @@ class AssumptionCache {
/// when we can write that to filter out the null values. Then caller code
/// will become simpler.
MutableArrayRef<WeakVH> assumptions() {
- if (!Scanned)
+ if (!isScanned())
scanFunction();
return AssumeHandles;
}
@@ -166,7 +168,7 @@ class AssumptionCache {
///
/// No more than -max-assumes-per-value of them are cached.
MutableArrayRef<ResultElem> assumptionsFor(const Value *V) {
- if (!Scanned)
+ if (!isScanned())
scanFunction();
auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
diff --git a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
index 5d9288ff2c2f3..283e97ec5e2f8 100644
--- a/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
+++ b/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
@@ -50,7 +50,7 @@ class BasicAAResult : public AAResultBase {
DominatorTree *DT_;
DominatorTree *getDT(const AAQueryInfo &AAQI) const {
- return AAQI.UseDominatorTree ? DT_ : nullptr;
+ return AAQI.usesDominatorTree() ? DT_ : nullptr;
}
public:
diff --git a/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index 29be24ce0c32a..4b585a8970b29 100644
--- a/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -22,6 +22,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
@@ -223,13 +224,22 @@ class LLVM_ABI BlockFrequencyInfoImplBase {
using NodeList = SmallVector<BlockNode, 4>;
LoopData *Parent; ///< The parent loop.
- bool IsPackaged = false; ///< Whether this has been packaged.
+ bool getIsPackaged() const { return Nodes.getFlag(0); }
+ void setIsPackaged(bool Value) {
+ Nodes.setFlag(0, Value);
+ } ///< Whether this has been packaged.
// Has an irreducible SCC in its own nodes; sub-loops package theirs first.
- bool ContainsIrreducible = false;
+ bool getContainsIrreducible() const { return Nodes.getFlag(1); }
+ bool setContainsIrreducible(bool Value) {
+ Nodes.setFlag(1, Value);
+ return Value;
+ }
// A multi-entry SCC rather than a natural loop.
- bool IsIrreducible = false;
+ bool getIsIrreducible() const { return Nodes.getFlag(2); }
+ void setIsIrreducible(bool Value) { Nodes.setFlag(2, Value); }
ExitMap Exits; ///< Successor edges (and weights).
- NodeList Nodes; ///< Header and the members of the loop.
+ llvm::SmallVectorWithFlagsFor<NodeList, 3>
+ Nodes; ///< Header and the members of the loop.
BlockMass BackedgeMass; ///< Mass that circulates, not exits.
BlockMass Mass;
Scaled64 Scale;
@@ -241,12 +251,12 @@ class LLVM_ABI BlockFrequencyInfoImplBase {
/// region is concerned, so the lowest-RPO member stands for the package
/// and solveIrreducibleMass distributes mass among them all.
LoopData(LoopData *Parent, NodeList &&Members)
- : Parent(Parent), IsIrreducible(true), Nodes(std::move(Members)) {}
+ : Parent(Parent), Nodes(4, std::move(Members)) {}
bool isHeader(const BlockNode &Node) const { return Node == Nodes[0]; }
BlockNode getHeader() const { return Nodes[0]; }
- bool isIrreducible() const { return IsIrreducible; }
+ bool isIrreducible() const { return getIsIrreducible(); }
NodeList::const_iterator members_begin() const { return Nodes.begin() + 1; }
@@ -300,10 +310,10 @@ class LLVM_ABI BlockFrequencyInfoImplBase {
/// Packaging is transient state: this answers what represents Node at the
/// level being processed, not where Node sits in the loop nest.
LoopData *getPackagedLoop() const {
- if (!Loop || !Loop->IsPackaged)
+ if (!Loop || !Loop->getIsPackaged())
return nullptr;
auto *L = Loop;
- while (L->Parent && L->Parent->IsPackaged)
+ while (L->Parent && L->Parent->getIsPackaged())
L = L->Parent;
return L;
}
@@ -312,7 +322,7 @@ class LLVM_ABI BlockFrequencyInfoImplBase {
/// loop it heads.
BlockMass &getMass() {
BlockMass *M = &Mass;
- for (LoopData *L = Loop; L && L->IsPackaged && L->isHeader(Node);
+ for (LoopData *L = Loop; L && L->getIsPackaged() && L->isHeader(Node);
L = L->Parent)
M = &L->Mass;
return *M;
@@ -322,7 +332,7 @@ class LLVM_ABI BlockFrequencyInfoImplBase {
bool isPackaged() const { return getResolvedNode() != Node; }
/// Has Loop been packaged up?
- bool isAPackage() const { return isLoopHeader() && Loop->IsPackaged; }
+ bool isAPackage() const { return isLoopHeader() && Loop->getIsPackaged(); }
};
/// Unscaled probability weight.
@@ -358,11 +368,11 @@ class LLVM_ABI BlockFrequencyInfoImplBase {
/// \a DidOverflow indicates whether \a Total did overflow while adding to
/// the distribution. It should never overflow twice.
struct Distribution {
- using WeightList = SmallVector<Weight, 4>;
+ // Flag bit 0 records overflow of the total weight.
+ using WeightList = SmallVectorWithFlags<Weight, 4>;
WeightList Weights; ///< Individual successor weights.
uint64_t Total = 0; ///< Sum of all weights.
- bool DidOverflow = false; ///< Whether \a Total did overflow.
Distribution() = default;
@@ -1074,7 +1084,7 @@ template <class BT> void BlockFrequencyInfoImpl<BT>::initializeLoops() {
// No LoopData yet; ask computeIrreducibleMass to package the SCC
// that contains this cycle.
if (Parent)
- Parent->ContainsIrreducible = true;
+ Parent->setContainsIrreducible(true);
else
TopContainsIrreducible = true;
}
@@ -1118,7 +1128,7 @@ template <class BT> void BlockFrequencyInfoImpl<BT>::computeMassInLoops() {
// computeIrreducibleMass inserts each new loop immediately after *L.
for (auto L = Loops.end(), B = Loops.begin(); L != B;) {
--L;
- if (L->ContainsIrreducible)
+ if (L->getContainsIrreducible())
computeIrreducibleMass(&*L, std::next(L));
computeMassInLoop(*L);
}
diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
index 4a03f548823ee..192fadc33d99e 100644
--- a/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
+++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -229,15 +230,15 @@ class GenericDomTreeUpdater {
DomTreeUpdate(CriticalEdge E) : IsCriticalEdgeSplit(true), EdgeSplit(E) {}
};
- SmallVector<DomTreeUpdate, 16> PendUpdates;
+ SmallVectorWithFlags<DomTreeUpdate, 16, 2> PendUpdates;
size_t PendDTUpdateIndex = 0;
size_t PendPDTUpdateIndex = 0;
DomTreeT *DT = nullptr;
PostDomTreeT *PDT = nullptr;
const UpdateStrategy Strategy;
SmallPtrSet<BasicBlockT *, 8> DeletedBBs;
- bool IsRecalculatingDomTree = false;
- bool IsRecalculatingPostDomTree = false;
+ bool isRecalculatingDomTree() const { return PendUpdates.getFlag(0); }
+ bool isRecalculatingPostDomTree() const { return PendUpdates.getFlag(1); }
/// Returns true if the update is self dominance.
bool isSelfDominance(UpdateT Update) const {
diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
index 6bfad783b529b..bcf7af736aea2 100644
--- a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
+++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
@@ -39,7 +39,7 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::recalculate(
// Lazy UpdateStrategy so we recalculate available trees immediately.
// Prevent forceFlushDeletedBB() from erasing DomTree or PostDomTree nodes.
- IsRecalculatingDomTree = IsRecalculatingPostDomTree = true;
+ PendUpdates.setFlags(3);
// Because all trees are going to be up-to-date after recalculation,
// flush awaiting deleted BasicBlocks.
@@ -50,7 +50,7 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::recalculate(
PDT->recalculate(F);
// Resume forceFlushDeletedBB() to erase DomTree or PostDomTree nodes.
- IsRecalculatingDomTree = IsRecalculatingPostDomTree = false;
+ PendUpdates.setFlags(0);
PendDTUpdateIndex = PendPDTUpdateIndex = PendUpdates.size();
dropOutOfDateUpdates();
}
@@ -330,11 +330,11 @@ bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isUpdateValid(
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::eraseDelBBNode(
BasicBlockT *DelBB) {
- if (DT && !IsRecalculatingDomTree)
+ if (DT && !isRecalculatingDomTree())
if (DT->getNode(DelBB))
DT->eraseNode(DelBB);
- if (PDT && !IsRecalculatingPostDomTree)
+ if (PDT && !isRecalculatingPostDomTree())
if (PDT->getNode(DelBB))
PDT->eraseNode(DelBB);
}
diff --git a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
index 5d18486fe8113..59176afe9097e 100644
--- a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -15,6 +15,7 @@
#define LLVM_ANALYSIS_LOOPACCESSANALYSIS_H
#include "llvm/ADT/EquivalenceClasses.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/Support/Compiler.h"
@@ -191,7 +192,7 @@ class MemoryDepChecker {
/// Print the dependence. \p Instr is used to map the instruction
/// indices to instructions.
LLVM_ABI void print(raw_ostream &OS, unsigned Depth,
- const SmallVectorImpl<Instruction *> &Instrs) const;
+ ArrayRef<Instruction *> Instrs) const;
};
MemoryDepChecker(PredicatedScalarEvolution &PSE, AssumptionCache *AC,
@@ -286,7 +287,7 @@ class MemoryDepChecker {
/// In same cases when the dependency check fails we can still
/// vectorize the loop with a dynamic array access check.
bool shouldRetryWithRuntimeChecks() const {
- return ShouldRetryWithRuntimeChecks &&
+ return InstMap.getFlag(0) &&
Status == VectorizationSafetyStatus::PossiblySafeWithRtChecks;
}
@@ -294,16 +295,14 @@ class MemoryDepChecker {
/// the MaxDependences threshold and this information is not
/// available.
const SmallVectorImpl<Dependence> *getDependences() const {
- return RecordDependences ? &Dependences : nullptr;
+ return recordDependences() ? &Dependences : nullptr;
}
void clearDependences() { Dependences.clear(); }
/// The vector of memory access instructions. The indices are used as
/// instruction identifiers in the Dependence class.
- const SmallVectorImpl<Instruction *> &getMemoryInstructions() const {
- return InstMap;
- }
+ ArrayRef<Instruction *> getMemoryInstructions() const { return InstMap; }
/// Generate a mapping between the memory instructions and their
/// indices according to program order.
@@ -370,7 +369,9 @@ class MemoryDepChecker {
DenseMap<MemAccessInfo, std::vector<unsigned> > Accesses;
/// Memory access instructions in program order.
- SmallVector<Instruction *, 16> InstMap;
+ // Flag bits 0 and 1 record retrying with runtime checks and invalid
+ // dependences.
+ SmallVectorWithFlags<Instruction *, 16, 2> InstMap;
/// The program order index to be used for the next instruction.
unsigned AccessIdx = 0;
@@ -393,7 +394,6 @@ class MemoryDepChecker {
/// Whether we should try to vectorize the loop with runtime checks, if the
/// dependencies are not safe.
- bool ShouldRetryWithRuntimeChecks = false;
/// Result of the dependence checks, indicating whether the checked
/// dependences are safe for vectorization, require RT checks or are known to
@@ -403,7 +403,7 @@ class MemoryDepChecker {
//// True if Dependences reflects the dependences in the
//// loop. If false we exceeded MaxDependences and
//// Dependences is invalid.
- bool RecordDependences = true;
+ bool recordDependences() const { return !InstMap.getFlag(1); }
/// Memory dependences collected during the analysis. Only valid if
/// RecordDependences is true.
@@ -588,8 +588,7 @@ class RuntimePointerChecking {
/// Reset the state of the pointer runtime information.
void reset() {
- Need = false;
- CanUseDiffCheck = true;
+ DiffChecks.setFlags(0);
Pointers.clear();
Checks.clear();
DiffChecks.clear();
@@ -623,7 +622,7 @@ class RuntimePointerChecking {
// if any pointer-difference is <u VF * InterleaveCount * access size. Returns
// std::nullopt if pointer-difference checks cannot be used.
std::optional<ArrayRef<PointerDiffInfo>> getDiffChecks() const {
- if (!CanUseDiffCheck)
+ if (DiffChecks.getFlag(1))
return std::nullopt;
return {DiffChecks};
}
@@ -646,7 +645,8 @@ class RuntimePointerChecking {
unsigned Depth = 0) const;
/// This flag indicates if we need to add the runtime check.
- bool Need = false;
+ bool needsChecking() const { return DiffChecks.getFlag(0); }
+ void setNeedsChecking(bool Need) { DiffChecks.setFlag(0, Need); }
/// Information about the pointers that may require checking.
SmallVector<PointerInfo, 2> Pointers;
@@ -706,11 +706,14 @@ class RuntimePointerChecking {
SmallVector<RuntimePointerCheck, 4> Checks;
/// Flag indicating if pointer-difference checks can be used
- bool CanUseDiffCheck = true;
/// A list of (pointer-difference, access size) pairs that can be used to
/// prove that there are no vectorization-preventing dependencies.
- SmallVector<PointerDiffInfo> DiffChecks;
+ // Flag bits 0 and 1 record required checks and unavailable diff checks.
+ SmallVectorWithFlags<
+ PointerDiffInfo,
+ CalculateSmallVectorDefaultInlinedElements<PointerDiffInfo>::value, 2>
+ DiffChecks;
};
/// Drive the analysis of memory accesses in the loop
diff --git a/llvm/include/llvm/Analysis/LoopCacheAnalysis.h b/llvm/include/llvm/Analysis/LoopCacheAnalysis.h
index 00ca85e97a636..7ba1f0c9c7b92 100644
--- a/llvm/include/llvm/Analysis/LoopCacheAnalysis.h
+++ b/llvm/include/llvm/Analysis/LoopCacheAnalysis.h
@@ -14,6 +14,7 @@
#ifndef LLVM_ANALYSIS_LOOPCACHEANALYSIS_H
#define LLVM_ANALYSIS_LOOPCACHEANALYSIS_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/InstructionCost.h"
@@ -55,7 +56,7 @@ class IndexedReference {
LLVM_ABI IndexedReference(Instruction &StoreOrLoadInst, const LoopInfo &LI,
ScalarEvolution &SE);
- bool isValid() const { return IsValid; }
+ bool isValid() const { return getIsValid(); }
const SCEV *getBasePointer() const { return BasePointer; }
size_t getNumSubscripts() const { return Subscripts.size(); }
const SCEV *getSubscript(unsigned SubNum) const {
@@ -137,7 +138,8 @@ class IndexedReference {
private:
/// True if the reference can be delinearized, false otherwise.
- bool IsValid = false;
+ bool getIsValid() const { return Sizes.getFlag(0); }
+ void setIsValid(bool Value) { Sizes.setFlag(0, Value); }
/// Represent the memory reference instruction.
Instruction &StoreOrLoadInst;
@@ -149,7 +151,7 @@ class IndexedReference {
SmallVector<const SCEV *, 3> Subscripts;
/// The dimensions of the memory reference.
- SmallVector<const SCEV *, 3> Sizes;
+ llvm::SmallVectorWithFlags<const SCEV *, 3> Sizes;
ScalarEvolution &SE;
};
diff --git a/llvm/include/llvm/Analysis/PtrUseVisitor.h b/llvm/include/llvm/Analysis/PtrUseVisitor.h
index 304c147190728..a11c9e906297e 100644
--- a/llvm/include/llvm/Analysis/PtrUseVisitor.h
+++ b/llvm/include/llvm/Analysis/PtrUseVisitor.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -137,7 +138,8 @@ class PtrUseVisitorBase {
};
/// The worklist of to-visit uses.
- SmallVector<UseToVisit, 8> Worklist;
+ // Flag bit 0 records whether the current offset is known.
+ SmallVectorWithFlags<UseToVisit, 8> Worklist;
/// A set of visited uses to break cycles in unreachable code.
SmallPtrSet<Use *, 8> VisitedUses;
@@ -153,7 +155,8 @@ class PtrUseVisitorBase {
/// True if we have a known constant offset for the use currently
/// being visited.
- bool IsOffsetKnown;
+ bool isOffsetKnown() const { return Worklist.getFlag(0); }
+ void setIsOffsetKnown(bool Known) { Worklist.setFlag(0, Known); }
/// The constant offset of the use if that is known.
APInt Offset;
@@ -228,7 +231,7 @@ class PtrUseVisitor : protected InstVisitor<DerivedT>,
assert(I.getType()->isPointerTy());
assert(isa<Instruction>(I) || isa<Argument>(I));
IntegerType *IntIdxTy = cast<IntegerType>(DL.getIndexType(I.getType()));
- IsOffsetKnown = true;
+ setIsOffsetKnown(true);
Offset = APInt(IntIdxTy->getBitWidth(), 0);
PI.reset();
@@ -239,8 +242,8 @@ class PtrUseVisitor : protected InstVisitor<DerivedT>,
while (!Worklist.empty()) {
UseToVisit ToVisit = Worklist.pop_back_val();
U = ToVisit.UseAndIsOffsetKnown.getPointer();
- IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt();
- if (IsOffsetKnown)
+ setIsOffsetKnown(ToVisit.UseAndIsOffsetKnown.getInt());
+ if (isOffsetKnown())
Offset = std::move(ToVisit.Offset);
Instruction *I = cast<Instruction>(U->getUser());
@@ -275,7 +278,7 @@ class PtrUseVisitor : protected InstVisitor<DerivedT>,
// If we can't walk the GEP, clear the offset.
if (!adjustOffsetForGEP(GEPI)) {
- IsOffsetKnown = false;
+ setIsOffsetKnown(false);
Offset = APInt();
}
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 298582cc1cf6b..acf22c68ad7ef 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -30,6 +30,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
@@ -1368,12 +1369,13 @@ class ScalarEvolution {
const SCEV *SymbolicMaxNotTaken;
// Not taken either exactly ConstantMaxNotTaken or zero times
- bool MaxOrZero = false;
+ bool isMaxOrZero() const { return Predicates.getFlag(0); }
/// A vector of predicate guards for this ExitLimit. The result is only
/// valid if all of the predicates in \c Predicates evaluate to 'true' at
/// run-time.
- SmallVector<const SCEVPredicate *, 4> Predicates;
+ // Flag bit 0 records whether the exit count is the maximum or zero.
+ SmallVectorWithFlags<const SCEVPredicate *, 4> Predicates;
/// Construct either an exact exit limit from a constant, or an unknown
/// one from a SCEVCouldNotCompute. No other types of SCEVs are allowed
@@ -1808,7 +1810,8 @@ class ScalarEvolution {
/// A list of computable exits and their not-taken counts. Loops almost
/// never have more than one computable exit.
- SmallVector<ExitNotTakenInfo, 1> ExitNotTaken;
+ // Flag bits 0 and 1 record completeness and a maximum-or-zero count.
+ SmallVectorWithFlags<ExitNotTakenInfo, 1, 2> ExitNotTaken;
/// Expression indicating the least constant maximum backedge-taken count of
/// the loop that is known, or a SCEVCouldNotCompute. This expression is
@@ -1817,16 +1820,14 @@ class ScalarEvolution {
/// Indicating if \c ExitNotTaken has an element for every exiting block in
/// the loop.
- bool IsComplete = false;
/// 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; }
+ bool isComplete() const { return ExitNotTaken.getFlag(0); }
const SCEV *getConstantMax() const { return ConstantMax; }
LLVM_ABI const ExitNotTakenInfo *getExitNotTaken(
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 42c11d72aa669..704a14328d07d 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -25,6 +25,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Uniformity.h"
#include "llvm/Analysis/IVDescriptors.h"
#include "llvm/Analysis/InterestingMemoryOperand.h"
@@ -87,16 +88,23 @@ struct MemIntrinsicInfo {
// Same Id is set by the target for corresponding load/store intrinsics.
unsigned short MatchingId = 0;
- bool ReadMem = false;
- bool WriteMem = false;
- bool IsVolatile = false;
+ bool getReadMem() const { return InterestingOperands.getFlag(0); }
+ bool setReadMem(bool Value) {
+ InterestingOperands.setFlag(0, Value);
+ return Value;
+ }
+ bool getWriteMem() const { return InterestingOperands.getFlag(1); }
+ void setWriteMem(bool Value) { InterestingOperands.setFlag(1, Value); }
+ bool getIsVolatile() const { return InterestingOperands.getFlag(2); }
+ void setIsVolatile(bool Value) { InterestingOperands.setFlag(2, Value); }
- SmallVector<InterestingMemoryOperand, 1> InterestingOperands;
+ llvm::SmallVectorWithFlags<InterestingMemoryOperand, 1, 3>
+ InterestingOperands;
bool isUnordered() const {
return (Ordering == AtomicOrdering::NotAtomic ||
Ordering == AtomicOrdering::Unordered) &&
- !IsVolatile;
+ !getIsVolatile();
}
};
diff --git a/llvm/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h b/llvm/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h
index 1cb29470e2ff7..833aac44b2e7f 100644
--- a/llvm/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h
+++ b/llvm/include/llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h
@@ -13,6 +13,7 @@
#define LLVM_ANALYSIS_UTILS_IMPORTEDFUNCTIONSINLININGSTATISTICS_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
@@ -51,14 +52,16 @@ class ImportedFunctionsInliningStatistics {
InlineGraphNode(InlineGraphNode &&) = default;
InlineGraphNode &operator=(InlineGraphNode &&) = default;
- llvm::SmallVector<InlineGraphNode *, 8> InlinedCallees;
+ llvm::SmallVectorWithFlags<InlineGraphNode *, 8, 2> 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;
+ bool getImported() const { return InlinedCallees.getFlag(0); }
+ void setImported(bool Value) { InlinedCallees.setFlag(0, Value); }
+ bool getVisited() const { return InlinedCallees.getFlag(1); }
+ void setVisited(bool Value) { InlinedCallees.setFlag(1, Value); }
};
public:
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index 70b98dae850fd..4173c06f3e109 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -13,6 +13,7 @@
#ifndef LLVM_ASMPARSER_LLPARSER_H
#define LLVM_ASMPARSER_LLPARSER_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/AsmParser/AsmParserContext.h"
#include "llvm/AsmParser/LLLexer.h"
@@ -185,15 +186,18 @@ namespace llvm {
SmallVector<std::tuple<LocTy, DbgRecord *, TrackingMDNodeRef>>
PendingDbgRecords;
- SmallVector<std::tuple<LocTy, Instruction *, TrackingMDNodeRef>>
+ SmallVectorWithFlagsFor<
+ SmallVector<std::tuple<LocTy, Instruction *, TrackingMDNodeRef>>, 2>
PendingDbgInsts;
- /// Only the llvm-as tool may set this to false to bypass
- /// UpgradeDebuginfo so it can generate broken bitcode.
- bool UpgradeDebugInfo;
-
- bool SeenNewDbgInfoFormat = false;
- bool SeenOldDbgInfoFormat = false;
+ bool getSeenNewDbgInfoFormat() const { return PendingDbgInsts.getFlag(0); }
+ void setSeenNewDbgInfoFormat(bool Value) {
+ PendingDbgInsts.setFlag(0, Value);
+ }
+ bool getSeenOldDbgInfoFormat() const { return PendingDbgInsts.getFlag(1); }
+ void setSeenOldDbgInfoFormat(bool Value) {
+ PendingDbgInsts.setFlag(1, Value);
+ }
std::string SourceFileName;
diff --git a/llvm/include/llvm/Bitstream/BitstreamWriter.h b/llvm/include/llvm/Bitstream/BitstreamWriter.h
index a2938642f824a..fda56318b8904 100644
--- a/llvm/include/llvm/Bitstream/BitstreamWriter.h
+++ b/llvm/include/llvm/Bitstream/BitstreamWriter.h
@@ -143,6 +143,14 @@ class BitstreamWriter {
}
public:
+ /// Create a bitstream in writer-owned storage.
+ BitstreamWriter() : Buffer(OwnBuffer), FS(nullptr), FlushThreshold(0) {}
+
+ /// Access the current storage. FlushToWord() completes any pending word.
+ /// Moving the buffer out finishes the stream; do not emit more data
+ /// afterward.
+ SmallVectorImpl<char> &getBuffer() { return Buffer; }
+
/// Create a BitstreamWriter over a raw_ostream \p OutStream.
/// If \p OutStream is a raw_svector_ostream, the BitstreamWriter will write
/// directly to the latter's buffer. In all other cases, the BitstreamWriter
diff --git a/llvm/include/llvm/CGData/StableFunctionMap.h b/llvm/include/llvm/CGData/StableFunctionMap.h
index 909d0e1debe7e..1733df1189c59 100644
--- a/llvm/include/llvm/CGData/StableFunctionMap.h
+++ b/llvm/include/llvm/CGData/StableFunctionMap.h
@@ -17,6 +17,7 @@
#define LLVM_CGDATA_STABLEFUNCTIONMAP_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/StructuralHash.h"
#include "llvm/Support/Compiler.h"
@@ -160,7 +161,7 @@ struct StableFunctionMap {
/// method assumes that string names have already been uniqued and the
/// `StableFunctionEntry` is ready for insertion.
void insert(std::unique_ptr<StableFunctionEntry> FuncEntry) {
- assert(!Finalized && "Cannot insert after finalization");
+ assert(!isFinalized() && "Cannot insert after finalization");
HashToFuncs[FuncEntry->Hash].Entries.emplace_back(std::move(FuncEntry));
}
@@ -174,18 +175,23 @@ struct StableFunctionMap {
/// A map from a stable_hash to a vector of functions with that hash.
mutable HashFuncsMapType HashToFuncs;
/// A vector of strings to hold names.
- SmallVector<std::string> IdToName;
+ // Flag bits 0 and 1 record finalization and disabled name loading.
+ SmallVectorWithFlags<
+ std::string,
+ CalculateSmallVectorDefaultInlinedElements<std::string>::value, 2>
+ IdToName;
/// A map from StringRef (name) to an ID.
StringMap<unsigned> NameToId;
/// True if the function map is finalized with minimal content.
- bool Finalized = false;
+ bool isFinalized() const { return IdToName.getFlag(0); }
/// The memory buffer that contains the serialized stable function map for
/// lazy loading.
/// Non-empty only if this StableFunctionMap is created from a MemoryBuffer
/// (i.e. by IndexedCodeGenDataReader::read()) and lazily deserialized.
std::shared_ptr<MemoryBuffer> Buffer;
/// Whether to read stable function names from the buffer.
- bool ReadStableFunctionMapNames = true;
+ bool readStableFunctionMapNames() const { return !IdToName.getFlag(1); }
+ void setReadStableFunctionMapNames(bool Read) { IdToName.setFlag(1, !Read); }
friend struct StableFunctionMapRecord;
};
diff --git a/llvm/include/llvm/CGData/StableFunctionMapRecord.h b/llvm/include/llvm/CGData/StableFunctionMapRecord.h
index 2d8b573a3cb46..0538c14ac4cba 100644
--- a/llvm/include/llvm/CGData/StableFunctionMapRecord.h
+++ b/llvm/include/llvm/CGData/StableFunctionMapRecord.h
@@ -109,7 +109,7 @@ struct StableFunctionMapRecord {
assert(
FunctionMap->empty() &&
"Cannot change ReadStableFunctionMapNames after the map is populated");
- FunctionMap->ReadStableFunctionMapNames = Read;
+ FunctionMap->setReadStableFunctionMapNames(Read);
}
private:
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 7278756a67267..8c26dfe734660 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/StaticDataProfileInfo.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -215,7 +216,8 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
DenseMap<GCStrategy *, std::unique_ptr<GCMetadataPrinter>> GCMetadataPrinters;
/// Emit comments in assembly output if this is true.
- bool VerboseAsm;
+ bool getVerboseAsm() const { return Sleds.getFlag(0); }
+ void setVerboseAsm(bool Value) { Sleds.setFlag(0, Value); }
/// Store symbols and type identifiers used to create callgraph section
/// entries related to a function.
@@ -254,7 +256,7 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
// A vector of all Debuginfo emitters we should use. Protected so that
// targets can add their own. This vector maintains ownership of the
// emitters.
- SmallVector<std::unique_ptr<AsmPrinterHandler>, 2> Handlers;
+ llvm::SmallVectorWithFlags<std::unique_ptr<AsmPrinterHandler>, 2> Handlers;
size_t NumUserHandlers = 0;
StackMaps SM;
@@ -279,15 +281,24 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
/// True if the module contains split-stack functions. This is used to
/// emit .note.GNU-split-stack section as required by the linker for
/// special handling split-stack function calling no-split-stack function.
- bool HasSplitStack = false;
+ bool getHasSplitStack() const { return Sleds.getFlag(1); }
+ void setHasSplitStack(bool Value) { Sleds.setFlag(1, Value); }
/// True if the module contains no-split-stack functions. This is used to emit
/// .note.GNU-no-split-stack section when it also contains functions without a
/// split stack prologue.
- bool HasNoSplitStack = false;
+ bool getHasNoSplitStack() const { return Sleds.getFlag(2); }
+ bool setHasNoSplitStack(bool Value) {
+ Sleds.setFlag(2, Value);
+ return Value;
+ }
/// True if debugging information is available in this module.
- bool DbgInfoAvailable = false;
+ bool getDbgInfoAvailable() const { return Sleds.getFlag(3); }
+ bool setDbgInfoAvailable(bool Value) {
+ Sleds.setFlag(3, Value);
+ return Value;
+ }
protected:
/// The attribute used for a pointer type's DWARF address space. Targets that
@@ -329,7 +340,7 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
bool isPositionIndependent() const;
/// Return true if assembly output should contain comments.
- bool isVerbose() const { return VerboseAsm; }
+ bool isVerbose() const { return getVerboseAsm(); }
/// Return a unique ID for the current function.
unsigned getFunctionNumber() const;
@@ -396,11 +407,11 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
MCSymbol *getSymbolPreferLocal(const GlobalValue &GV) const;
bool doesDwarfUseRelocationsAcrossSections() const {
- return DwarfUsesRelocationsAcrossSections;
+ return getDwarfUsesRelocationsAcrossSectionsFlag();
}
void setDwarfUsesRelocationsAcrossSections(bool Enable) {
- DwarfUsesRelocationsAcrossSections = Enable;
+ setDwarfUsesRelocationsAcrossSectionsFlag(Enable);
}
/// Returns a section suffix (hot or unlikely) for the constant if profiles
@@ -445,7 +456,7 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
};
// All the sleds to be emitted.
- SmallVector<XRayFunctionEntry, 4> Sleds;
+ llvm::SmallVectorWithFlags<XRayFunctionEntry, 4, 4> Sleds;
// Helper function to record a given XRay sled.
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind,
@@ -534,7 +545,7 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
CFISection getModuleCFISectionType() const { return ModuleCFISection; }
/// Returns true if valid debug info is present.
- bool hasDebugInfo() const { return DbgInfoAvailable; }
+ bool hasDebugInfo() const { return getDbgInfoAvailable(); }
/// Since emitting CFI unwind information is entangled with supporting the
/// exceptions, this returns true for platforms which use CFI unwind
@@ -988,7 +999,12 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
mutable unsigned LastFn = 0;
mutable unsigned Counter = ~0U;
- bool DwarfUsesRelocationsAcrossSections = false;
+ bool getDwarfUsesRelocationsAcrossSectionsFlag() const {
+ return Handlers.getFlag(0);
+ }
+ void setDwarfUsesRelocationsAcrossSectionsFlag(bool Value) {
+ Handlers.setFlag(0, Value);
+ }
/// This method emits the header for the current function.
virtual void emitFunctionHeader();
diff --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h
index 45703744efe3a..447bc539b8617 100644
--- a/llvm/include/llvm/CodeGen/CallingConvLower.h
+++ b/llvm/include/llvm/CodeGen/CallingConvLower.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/TargetCallingConv.h"
#include "llvm/IR/CallingConv.h"
@@ -171,14 +172,21 @@ typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT,
class CCState {
private:
CallingConv::ID CallingConv;
- bool IsVarArg;
- bool AnalyzingMustTailForwardedRegs = false;
+ bool getIsVarArg() const { return ByValRegs.getFlag(0); }
+ void setIsVarArg(bool Value) { ByValRegs.setFlag(0, Value); }
+ bool getAnalyzingMustTailForwardedRegs() const {
+ return ByValRegs.getFlag(1);
+ }
+ void setAnalyzingMustTailForwardedRegs(bool Value) {
+ ByValRegs.setFlag(1, Value);
+ }
MachineFunction &MF;
const TargetRegisterInfo &TRI;
SmallVectorImpl<CCValAssign> &Locs;
LLVMContext &Context;
// True if arguments should be allocated at negative offsets.
- bool NegativeOffsets;
+ bool getNegativeOffsets() const { return ByValRegs.getFlag(2); }
+ void setNegativeOffsets(bool Value) { ByValRegs.setFlag(2, Value); }
uint64_t StackSize;
Align MaxStackArgAlign;
@@ -222,7 +230,7 @@ class CCState {
// First after last register allocated for current parameter.
unsigned End;
};
- SmallVector<ByValInfo, 4 > ByValRegs;
+ llvm::SmallVectorWithFlags<ByValInfo, 4, 3> ByValRegs;
// InRegsParamsProcessed - shows how many instances of ByValRegs was proceed
// during argument analysis.
@@ -240,7 +248,7 @@ class CCState {
LLVMContext &getContext() const { return Context; }
MachineFunction &getMachineFunction() const { return MF; }
CallingConv::ID getCallingConv() const { return CallingConv; }
- bool isVarArg() const { return IsVarArg; }
+ bool isVarArg() const { return getIsVarArg(); }
/// Returns the size of the currently allocated portion of the stack.
uint64_t getStackSize() const { return StackSize; }
@@ -260,30 +268,27 @@ class CCState {
/// AnalyzeFormalArguments - Analyze an array of argument values,
/// incorporating info about the formals into this state.
- LLVM_ABI void
- AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
- CCAssignFn Fn);
+ LLVM_ABI void AnalyzeFormalArguments(llvm::ArrayRef<ISD::InputArg> Ins,
+ CCAssignFn Fn);
/// The function will invoke AnalyzeFormalArguments.
- void AnalyzeArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
- CCAssignFn Fn) {
+ void AnalyzeArguments(llvm::ArrayRef<ISD::InputArg> Ins, CCAssignFn Fn) {
AnalyzeFormalArguments(Ins, Fn);
}
/// AnalyzeReturn - Analyze the returned values of a return,
/// incorporating info about the result values into this state.
- LLVM_ABI void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
+ LLVM_ABI void AnalyzeReturn(llvm::ArrayRef<ISD::OutputArg> Outs,
CCAssignFn Fn);
/// CheckReturn - Analyze the return values of a function, returning
/// true if the return can be performed without sret-demotion, and
/// false otherwise.
- LLVM_ABI bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
- CCAssignFn Fn);
+ LLVM_ABI bool CheckReturn(llvm::ArrayRef<ISD::OutputArg> Outs, CCAssignFn Fn);
/// AnalyzeCallOperands - Analyze the outgoing arguments to a call,
/// incorporating info about the passed values into this state.
- LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
+ LLVM_ABI void AnalyzeCallOperands(llvm::ArrayRef<ISD::OutputArg> Outs,
CCAssignFn Fn);
/// AnalyzeCallOperands - Same as above except it takes vectors of types
@@ -294,14 +299,13 @@ class CCState {
CCAssignFn Fn);
/// The function will invoke AnalyzeCallOperands.
- void AnalyzeArguments(const SmallVectorImpl<ISD::OutputArg> &Outs,
- CCAssignFn Fn) {
+ void AnalyzeArguments(llvm::ArrayRef<ISD::OutputArg> Outs, CCAssignFn Fn) {
AnalyzeCallOperands(Outs, Fn);
}
/// AnalyzeCallResult - Analyze the return values of a call,
/// incorporating info about the passed values into this state.
- LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
+ LLVM_ABI void AnalyzeCallResult(llvm::ArrayRef<ISD::InputArg> Ins,
CCAssignFn Fn);
/// A shadow allocated register is a register that was allocated
@@ -407,7 +411,7 @@ class CCState {
/// and alignment.
int64_t AllocateStack(unsigned Size, Align Alignment) {
int64_t Offset;
- if (NegativeOffsets) {
+ if (getNegativeOffsets()) {
StackSize = alignTo(StackSize + Size, Alignment);
Offset = -StackSize;
} else {
@@ -507,18 +511,19 @@ class CCState {
/// Returns true if the results of the two calling conventions are compatible.
/// This is usually part of the check for tailcall eligibility.
- LLVM_ABI static bool
- resultsCompatible(CallingConv::ID CalleeCC, CallingConv::ID CallerCC,
- MachineFunction &MF, LLVMContext &C,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- CCAssignFn CalleeFn, CCAssignFn CallerFn);
+ LLVM_ABI static bool resultsCompatible(CallingConv::ID CalleeCC,
+ CallingConv::ID CallerCC,
+ MachineFunction &MF, LLVMContext &C,
+ llvm::ArrayRef<ISD::InputArg> Ins,
+ CCAssignFn CalleeFn,
+ CCAssignFn CallerFn);
/// The function runs an additional analysis pass over function arguments.
/// It will mark each argument with the attribute flag SecArgPass.
/// After running, it will sort the locs list.
- template <class T>
- void AnalyzeArgumentsSecondPass(const SmallVectorImpl<T> &Args,
- CCAssignFn Fn) {
+ template <class ArgRangeT>
+ void AnalyzeArgumentsSecondPass(const ArgRangeT &Args, CCAssignFn Fn) {
+ using T = typename ArgRangeT::value_type;
unsigned NumFirstPassLocs = Locs.size();
/// Creates similar argument list to \p Args in which each argument is
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
index 1627d57a5b1f3..22014b11e076e 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/TargetCallingConv.h"
@@ -115,7 +116,7 @@ class LLVM_ABI CallLowering {
ArgInfo OrigRet;
/// List of descriptors of the arguments passed to the function.
- SmallVector<ArgInfo, 32> OrigArgs;
+ llvm::SmallVectorWithFlags<ArgInfo, 32, 2> OrigArgs;
/// Valid if the call has a swifterror inout parameter, and contains the
/// vreg that the swifterror should be copied into after the call.
@@ -159,10 +160,12 @@ class LLVM_ABI CallLowering {
const ConstantInt *CFIType = nullptr;
/// True if this call results in convergent operations.
- bool IsConvergent = true;
+ bool getIsConvergent() const { return !OrigArgs.getFlag(0); }
+ void setIsConvergent(bool Value) { OrigArgs.setFlag(0, !Value); }
/// True if this call must not be merged with other calls.
- bool NoMerge = false;
+ bool getNoMerge() const { return OrigArgs.getFlag(1); }
+ void setNoMerge(bool Value) { OrigArgs.setFlag(1, Value); }
GlobalValue *DeactivationSymbol = nullptr;
};
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GISelWorkList.h b/llvm/include/llvm/CodeGen/GlobalISel/GISelWorkList.h
index 709490fcfc0f8..0d3af2aa8e090 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GISelWorkList.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GISelWorkList.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace llvm {
@@ -25,11 +26,16 @@ class MachineInstr;
// instcombinerWorkList?
template<unsigned N>
class GISelWorkList {
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+ SmallVectorWithFlags<MachineInstr *, N> Worklist;
+#else
SmallVector<MachineInstr *, N> Worklist;
+#endif
DenseMap<MachineInstr *, unsigned> WorklistMap;
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
- bool Finalized = true;
+ bool isFinalized() const { return !Worklist.getFlag(0); }
+ void setFinalized(bool Value) { Worklist.setFlag(0, !Value); }
#endif
public:
@@ -48,7 +54,7 @@ class GISelWorkList {
void deferred_insert(MachineInstr *I) {
Worklist.push_back(I);
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
- Finalized = false;
+ setFinalized(false);
#endif
}
@@ -64,14 +70,14 @@ class GISelWorkList {
if (!WorklistMap.try_emplace(Worklist[i], i).second)
llvm_unreachable("Duplicate elements in the list");
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
- Finalized = true;
+ setFinalized(true);
#endif
}
/// Add the specified instruction to the worklist if it isn't already in it.
void insert(MachineInstr *I) {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
- assert(Finalized && "GISelWorkList used without finalizing");
+ assert(isFinalized() && "GISelWorkList used without finalizing");
#endif
if (WorklistMap.try_emplace(I, Worklist.size()).second)
Worklist.push_back(I);
@@ -80,7 +86,7 @@ class GISelWorkList {
/// Remove I from the worklist if it exists.
void remove(const MachineInstr *I) {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
- assert(Finalized && "GISelWorkList used without finalizing");
+ assert(isFinalized() && "GISelWorkList used without finalizing");
#endif
auto It = WorklistMap.find(I);
if (It == WorklistMap.end())
@@ -99,7 +105,7 @@ class GISelWorkList {
MachineInstr *pop_back_val() {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
- assert(Finalized && "GISelWorkList used without finalizing");
+ assert(isFinalized() && "GISelWorkList used without finalizing");
#endif
MachineInstr *I;
do {
diff --git a/llvm/include/llvm/CodeGen/LexicalScopes.h b/llvm/include/llvm/CodeGen/LexicalScopes.h
index 6a52bdfb2f48c..ebaf026a7fcc4 100644
--- a/llvm/include/llvm/CodeGen/LexicalScopes.h
+++ b/llvm/include/llvm/CodeGen/LexicalScopes.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
@@ -45,7 +46,8 @@ class LexicalScope {
public:
LexicalScope(LexicalScope *P, const DILocalScope *D, const DILocation *I,
bool A)
- : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A) {
+ : Parent(P), Desc(D), InlinedAtLocation(I) {
+ Children.setFlag(0, A);
assert(D);
assert(D->getSubprogram()->getUnit()->getEmissionKind() !=
DICompileUnit::NoDebug &&
@@ -64,8 +66,8 @@ class LexicalScope {
const MDNode *getDesc() const { return Desc; }
const DILocation *getInlinedAt() const { return InlinedAtLocation; }
const DILocalScope *getScopeNode() const { return Desc; }
- bool isAbstractScope() const { return AbstractScope; }
- SmallVectorImpl<LexicalScope *> &getChildren() { return Children; }
+ bool isAbstractScope() const { return Children.getFlag(0); }
+ SmallVectorWithFlagsImpl<LexicalScope *> &getChildren() { return Children; }
SmallVectorImpl<InsnRange> &getRanges() { return Ranges; }
/// Add a child scope.
@@ -125,9 +127,9 @@ class LexicalScope {
const DILocalScope *Desc; // Debug info descriptor.
const DILocation *InlinedAtLocation; // Location at which this
// scope is inlined.
- bool AbstractScope; // Abstract Scope
- SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope.
- // Contents not owned.
+ // Flag bit 0 marks an abstract scope.
+ SmallVectorWithFlags<LexicalScope *, 4> Children; // Scopes defined in scope.
+ // Contents not owned.
SmallVector<InsnRange, 4> Ranges;
const MachineInstr *LastInsn = nullptr; // Last instruction of this scope.
diff --git a/llvm/include/llvm/CodeGen/LiveIntervalUnion.h b/llvm/include/llvm/CodeGen/LiveIntervalUnion.h
index 9b0423486db88..a9917dbfb52bf 100644
--- a/llvm/include/llvm/CodeGen/LiveIntervalUnion.h
+++ b/llvm/include/llvm/CodeGen/LiveIntervalUnion.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include <cassert>
@@ -119,9 +120,17 @@ class LiveIntervalUnion {
const LiveRange *LR = nullptr;
LiveRange::const_iterator LRI; ///< current position in LR
ConstSegmentIter LiveUnionI; ///< current position in LiveUnion
- SmallVector<const LiveInterval *, 4> InterferingVRegs;
- bool CheckedFirstInterference = false;
- bool SeenAllInterferences = false;
+ llvm::SmallVectorWithFlags<const LiveInterval *, 4, 2> InterferingVRegs;
+ bool getCheckedFirstInterference() const {
+ return InterferingVRegs.getFlag(0);
+ }
+ void setCheckedFirstInterference(bool Value) {
+ InterferingVRegs.setFlag(0, Value);
+ }
+ bool getSeenAllInterferences() const { return InterferingVRegs.getFlag(1); }
+ void setSeenAllInterferences(bool Value) {
+ InterferingVRegs.setFlag(1, Value);
+ }
unsigned Tag = 0;
unsigned UserTag = 0;
@@ -144,8 +153,8 @@ class LiveIntervalUnion {
LiveUnion = &NewLiveUnion;
LR = &NewLR;
InterferingVRegs.clear();
- CheckedFirstInterference = false;
- SeenAllInterferences = false;
+ setCheckedFirstInterference(false);
+ setSeenAllInterferences(false);
Tag = NewLiveUnion.getTag();
UserTag = NewUserTag;
}
@@ -164,9 +173,10 @@ class LiveIntervalUnion {
bool checkInterference() { return collectInterferingVRegs(1); }
// Vector generated by collectInterferingVRegs.
- const SmallVectorImpl<const LiveInterval *> &interferingVRegs(
+ ArrayRef<const LiveInterval *> interferingVRegs(
unsigned MaxInterferingRegs = std::numeric_limits<unsigned>::max()) {
- if (!SeenAllInterferences || MaxInterferingRegs < InterferingVRegs.size())
+ if (!getSeenAllInterferences() ||
+ MaxInterferingRegs < InterferingVRegs.size())
collectInterferingVRegs(MaxInterferingRegs);
return InterferingVRegs;
}
diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index 8a928e1e75682..bee66823e1bc7 100644
--- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/iterator_range.h"
@@ -151,7 +152,9 @@ class MachineBasicBlock
Instructions Insts;
/// Keep track of the predecessor / successor basic blocks.
- SmallVector<MachineBasicBlock *, 4> Predecessors;
+ // Flag bits 0-3 mark cleanup funclets, section boundaries, and asm-br
+ // targets.
+ SmallVectorWithFlags<MachineBasicBlock *, 4, 4> Predecessors;
SmallVector<MachineBasicBlock *, 2> Successors;
/// Keep track of the probabilities to the successors. This vector has the
@@ -206,7 +209,6 @@ class MachineBasicBlock
bool IsEHFuncletEntry = false;
/// Indicate that this basic block is the entry block of a cleanup funclet.
- bool IsCleanupFuncletEntry = false;
/// Fixed unique ID assigned to this basic block upon creation. Used with
/// basic block sections and basic block labels.
@@ -216,13 +218,10 @@ class MachineBasicBlock
MBBSectionID SectionID{0};
// Indicate that this basic block begins a section.
- bool IsBeginSection = false;
// Indicate that this basic block ends a section.
- bool IsEndSection = false;
/// Indicate that this basic block is the indirect dest of an INLINEASM_BR.
- bool IsInlineAsmBrIndirectTarget = false;
/// since getSymbol is a relatively heavy-weight operation, the symbol
/// is only computed once and is cached.
@@ -280,7 +279,7 @@ class MachineBasicBlock
/// more detailed checks that this function aggregates together.
bool hasAddressTaken() const {
return MachineBlockAddressTaken || AddressTakenIRBlock ||
- IsInlineAsmBrIndirectTarget;
+ isInlineAsmBrIndirectTarget();
}
/// Test whether this block is used as something other than the target of a
@@ -692,20 +691,20 @@ class MachineBasicBlock
void setIsEHFuncletEntry(bool V = true) { IsEHFuncletEntry = V; }
/// Returns true if this is the entry block of a cleanup funclet.
- bool isCleanupFuncletEntry() const { return IsCleanupFuncletEntry; }
+ bool isCleanupFuncletEntry() const { return Predecessors.getFlag(0); }
/// Indicates if this is the entry block of a cleanup funclet.
- void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
+ void setIsCleanupFuncletEntry(bool V = true) { Predecessors.setFlag(0, V); }
/// Returns true if this block begins any section.
- bool isBeginSection() const { return IsBeginSection; }
+ bool isBeginSection() const { return Predecessors.getFlag(1); }
/// Returns true if this block ends any section.
- bool isEndSection() const { return IsEndSection; }
+ bool isEndSection() const { return Predecessors.getFlag(2); }
- void setIsBeginSection(bool V = true) { IsBeginSection = V; }
+ void setIsBeginSection(bool V = true) { Predecessors.setFlag(1, V); }
- void setIsEndSection(bool V = true) { IsEndSection = V; }
+ void setIsEndSection(bool V = true) { Predecessors.setFlag(2, V); }
std::optional<UniqueBBID> getBBID() const { return BBID; }
@@ -730,13 +729,11 @@ class MachineBasicBlock
LLVM_ABI bool mayHaveInlineAsmBr() const;
/// Returns true if this is the indirect dest of an INLINEASM_BR.
- bool isInlineAsmBrIndirectTarget() const {
- return IsInlineAsmBrIndirectTarget;
- }
+ bool isInlineAsmBrIndirectTarget() const { return Predecessors.getFlag(3); }
/// Indicates if this is the indirect dest of an INLINEASM_BR.
void setIsInlineAsmBrIndirectTarget(bool V = true) {
- IsInlineAsmBrIndirectTarget = V;
+ Predecessors.setFlag(3, V);
}
/// Returns true if it is legal to hoist instructions into this block.
diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index 30699c3c18f1c..f0a9d27f59389 100644
--- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -14,6 +14,7 @@
#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/Support/Alignment.h"
@@ -248,7 +249,8 @@ class MachineFrameInfo {
/// This boolean keeps track of whether there is a call
/// to builtin \@llvm.experimental.patchpoint.
- bool HasPatchPoint = false;
+ bool getHasPatchPointFlag() const { return LocalFrameObjects.getFlag(0); }
+ void setHasPatchPointFlag(bool Value) { LocalFrameObjects.setFlag(0, Value); }
/// The prolog/epilog code inserter calculates the final stack
/// offsets for all of the fixed size objects, updating the Objects list
@@ -311,11 +313,12 @@ class MachineFrameInfo {
std::vector<CalleeSavedInfo> CSInfo;
/// Has CSInfo been set yet?
- bool CSIValid = false;
+ bool getCSIValid() const { return LocalFrameObjects.getFlag(1); }
+ void setCSIValid(bool Value) { LocalFrameObjects.setFlag(1, Value); }
/// References to frame indices which are mapped
/// into the local frame allocation block. <FrameIdx, LocalOffset>
- SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects;
+ llvm::SmallVectorWithFlags<std::pair<int, int64_t>, 32, 2> LocalFrameObjects;
/// Size of the pre-allocated local frame block.
int64_t LocalFrameSize = 0;
@@ -406,8 +409,8 @@ class MachineFrameInfo {
/// This method may be called any time after instruction
/// selection is complete to determine if there is a call to builtin
/// \@llvm.experimental.patchpoint.
- bool hasPatchPoint() const { return HasPatchPoint; }
- void setHasPatchPoint(bool s = true) { HasPatchPoint = s; }
+ bool hasPatchPoint() const { return getHasPatchPointFlag(); }
+ void setHasPatchPoint(bool s = true) { setHasPatchPointFlag(s); }
/// Return true if this function requires a split stack prolog, even if it
/// uses no stack space. This is only meaningful for functions where
@@ -869,9 +872,9 @@ class MachineFrameInfo {
}
/// Has the callee saved info been calculated yet?
- bool isCalleeSavedInfoValid() const { return CSIValid; }
+ bool isCalleeSavedInfoValid() const { return getCSIValid(); }
- void setCalleeSavedInfoValid(bool v) { CSIValid = v; }
+ void setCalleeSavedInfoValid(bool v) { setCSIValid(v); }
const SaveRestorePoints &getRestorePoints() const { return RestorePoints; }
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index 7a6f71b5648a6..0715881858a42 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/iterator.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -402,9 +403,20 @@ class LLVM_ABI MachineFunction {
bool CallsUnwindInit = false;
bool HasEHContTarget = false;
bool HasEHScopes = false;
- bool HasEHFunclets = false;
- bool HasFakeUses = false;
- bool IsOutlined = false;
+ bool getHasEHFuncletsFlag() const {
+ return DebugValueSubstitutions.getFlag(0);
+ }
+ void setHasEHFuncletsFlag(bool Value) {
+ DebugValueSubstitutions.setFlag(0, Value);
+ }
+ bool getHasFakeUsesFlag() const { return DebugValueSubstitutions.getFlag(1); }
+ void setHasFakeUsesFlag(bool Value) {
+ DebugValueSubstitutions.setFlag(1, Value);
+ }
+ bool getIsOutlinedFlag() const { return DebugValueSubstitutions.getFlag(2); }
+ void setIsOutlinedFlag(bool Value) {
+ DebugValueSubstitutions.setFlag(2, Value);
+ }
/// BBID to assign to the next basic block of this function.
unsigned NextBBID = 0;
@@ -609,7 +621,7 @@ class LLVM_ABI MachineFunction {
/// recording changes in where a value is defined. For example, when one
/// instruction is substituted for another. Keeping a record allows recovery
/// of variable locations after compilation finishes.
- SmallVector<DebugSubstitution, 8> DebugValueSubstitutions;
+ llvm::SmallVectorWithFlags<DebugSubstitution, 8, 4> DebugValueSubstitutions;
/// Location of a PHI instruction that is also a debug-info variable value,
/// for the duration of register allocation. Loaded by the PHI-elimination
@@ -631,7 +643,12 @@ class LLVM_ABI MachineFunction {
/// Flag for whether this function contains DBG_VALUEs (false) or
/// DBG_INSTR_REF (true).
- bool UseDebugInstrRef = false;
+ bool getUseDebugInstrRefFlag() const {
+ return DebugValueSubstitutions.getFlag(3);
+ }
+ void setUseDebugInstrRefFlag(bool Value) {
+ DebugValueSubstitutions.setFlag(3, Value);
+ }
/// Create a substitution between one <instr,operand> value to a different,
/// new value.
@@ -1323,14 +1340,14 @@ class LLVM_ABI MachineFunction {
bool hasEHScopes() const { return HasEHScopes; }
void setHasEHScopes(bool V) { HasEHScopes = V; }
- bool hasEHFunclets() const { return HasEHFunclets; }
- void setHasEHFunclets(bool V) { HasEHFunclets = V; }
+ bool hasEHFunclets() const { return getHasEHFuncletsFlag(); }
+ void setHasEHFunclets(bool V) { setHasEHFuncletsFlag(V); }
- bool hasFakeUses() const { return HasFakeUses; }
- void setHasFakeUses(bool V) { HasFakeUses = V; }
+ bool hasFakeUses() const { return getHasFakeUsesFlag(); }
+ void setHasFakeUses(bool V) { setHasFakeUsesFlag(V); }
- bool isOutlined() const { return IsOutlined; }
- void setIsOutlined(bool V) { IsOutlined = V; }
+ bool isOutlined() const { return getIsOutlinedFlag(); }
+ void setIsOutlined(bool V) { setIsOutlinedFlag(V); }
/// Find or create an LandingPadInfo for the specified MachineBasicBlock.
LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
diff --git a/llvm/include/llvm/CodeGen/MachinePipeliner.h b/llvm/include/llvm/CodeGen/MachinePipeliner.h
index 9b8beef1a1677..01989fd23a23e 100644
--- a/llvm/include/llvm/CodeGen/MachinePipeliner.h
+++ b/llvm/include/llvm/CodeGen/MachinePipeliner.h
@@ -42,6 +42,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineDominators.h"
@@ -625,7 +626,7 @@ class ResourceManager {
const TargetSubtargetInfo *ST;
const TargetInstrInfo *TII;
ScheduleDAGInstrs *DAG;
- const bool UseDFA;
+ bool getUseDFA() const { return NumScheduledMops.getFlag(0); }
/// DFA resources for each slot
llvm::SmallVector<std::unique_ptr<DFAPacketizer>> DFAResources;
/// Modulo Reservation Table. When a resource with ID R is consumed in cycle
@@ -634,7 +635,7 @@ class ResourceManager {
/// The number of scheduled micro operations for each slot. Micro operations
/// are assumed to be scheduled one per cycle, starting with the cycle in
/// which the instruction is scheduled.
- llvm::SmallVector<int> NumScheduledMops;
+ llvm::SmallVectorWithFlags<int> NumScheduledMops;
/// Each processor resource is associated with a so-called processor resource
/// mask. This vector allows to correlate processor resource IDs with
/// processor resource masks. There is exactly one element per each processor
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index a5cd22f2c5d9a..e33611dad50f3 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -80,7 +81,6 @@ class MachineRegisterInfo {
SmallPtrSet<Delegate *, 1> TheDelegates;
/// True if subregister liveness is tracked.
- const bool TracksSubRegLiveness;
/// VRegInfo - Information we keep for each virtual register.
///
@@ -99,12 +99,12 @@ class MachineRegisterInfo {
/// The flag is true upon \p UpdatedCSRs initialization
/// and false otherwise.
- bool IsUpdatedCSRsInitialized = false;
/// Contains the updated callee saved register list.
/// As opposed to the static list defined in register info,
/// all registers that were disabled are removed from the list.
- SmallVector<MCPhysReg, 16> UpdatedCSRs;
+ // Flag bits 0 and 1 track subregister liveness and CSR initialization.
+ SmallVectorWithFlags<MCPhysReg, 16, 2> UpdatedCSRs;
/// RegAllocHints - This vector records register allocation hints for
/// virtual registers. For each virtual register, it keeps a pair of hint
@@ -247,16 +247,14 @@ class MachineRegisterInfo {
const TargetRegisterClass *RC = getRegClassOrNull(VReg);
return LLVM_LIKELY(RC) ? shouldTrackSubRegLiveness(*RC) : false;
}
- bool subRegLivenessEnabled() const {
- return TracksSubRegLiveness;
- }
+ bool subRegLivenessEnabled() const { return UpdatedCSRs.getFlag(0); }
//===--------------------------------------------------------------------===//
// Register Info
//===--------------------------------------------------------------------===//
/// Returns true if the updated CSR list was initialized and false otherwise.
- bool isUpdatedCSRsInitialized() const { return IsUpdatedCSRsInitialized; }
+ bool isUpdatedCSRsInitialized() const { return UpdatedCSRs.getFlag(1); }
/// Disables the register from the list of CSRs.
/// I.e. the register will not appear as part of the CSR mask.
diff --git a/llvm/include/llvm/CodeGen/MachineScheduler.h b/llvm/include/llvm/CodeGen/MachineScheduler.h
index 7ecc34fed40f8..9e4d13f9401f1 100644
--- a/llvm/include/llvm/CodeGen/MachineScheduler.h
+++ b/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -79,6 +79,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -95,8 +96,8 @@
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
-#include <llvm/Support/raw_ostream.h>
#include <list>
+#include <llvm/Support/raw_ostream.h>
#include <memory>
#include <string>
#include <vector>
@@ -883,7 +884,10 @@ class SchedBoundary {
private:
/// True if the pending Q should be checked/updated before scheduling another
/// instruction.
- bool CheckPending;
+ bool getCheckPending() const { return ResourceGroupSubUnitMasks.getFlag(0); }
+ void setCheckPending(bool Value) {
+ ResourceGroupSubUnitMasks.setFlag(0, Value);
+ }
/// Number of cycles it takes to issue the instructions scheduled in this
/// zone. It is defined as: scheduled-micro-ops / issue-width + stalls.
@@ -922,7 +926,13 @@ class SchedBoundary {
unsigned ZoneCritResIdx;
// Is the scheduled region resource limited vs. latency limited.
- bool IsResourceLimited;
+ bool getIsResourceLimited() const {
+ return ResourceGroupSubUnitMasks.getFlag(1);
+ }
+ bool setIsResourceLimited(bool Value) {
+ ResourceGroupSubUnitMasks.setFlag(1, Value);
+ return Value;
+ }
public:
private:
@@ -962,7 +972,7 @@ class SchedBoundary {
SmallVector<unsigned, 16> ReservedCyclesIndex;
// For each PIdx, stores the resource group IDs of its subunits
- SmallVector<APInt, 16> ResourceGroupSubUnitMasks;
+ llvm::SmallVectorWithFlags<APInt, 16, 2> ResourceGroupSubUnitMasks;
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
// Remember the greatest possible stall as an upper bound on the number of
@@ -1033,7 +1043,7 @@ class SchedBoundary {
unsigned getZoneCritResIdx() const { return ZoneCritResIdx; }
// Is the scheduled region resource limited vs. latency limited.
- bool isResourceLimited() const { return IsResourceLimited; }
+ bool isResourceLimited() const { return getIsResourceLimited(); }
/// Get the difference between the given SUnit's ready time and the current
/// cycle.
diff --git a/llvm/include/llvm/CodeGen/Rematerializer.h b/llvm/include/llvm/CodeGen/Rematerializer.h
index 9dda2a47b4387..918a9dd7f814c 100644
--- a/llvm/include/llvm/CodeGen/Rematerializer.h
+++ b/llvm/include/llvm/CodeGen/Rematerializer.h
@@ -15,6 +15,7 @@
#define LLVM_CODEGEN_REMATERIALIZER_H
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/LiveRangeEdit.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -620,7 +621,7 @@ class LLVM_ABI Rollbacker : public Rematerializer::Listener {
/// in register deletion order overall. A position is either a MachineInstr*
/// that existed in the MIR at the time the rollbacker was attached to the
/// rematerializer, or a MachineBasicBlock*.
- SmallVector<InsertBeforePos> Positions;
+ llvm::SmallVectorWithFlags<InsertBeforePos> Positions;
/// Maps all re-creation positions that exist in \ref Positions to the indices
/// of elements holding that position in the vector.
DenseMap<InsertBeforePos, SmallDenseSet<unsigned, 1>> PosToIdx;
@@ -629,7 +630,8 @@ class LLVM_ABI Rollbacker : public Rematerializer::Listener {
DenseMap<RegisterIdx, Rematerializer::RematsOf> Rematerializations;
/// Used to block further recording of events whenver we are actively rolling
/// back.
- bool RollingBack = false;
+ bool getRollingBack() const { return Positions.getFlag(0); }
+ void setRollingBack(bool Value) { Positions.setFlag(0, Value); }
InsertBeforePos makePos(MachineBasicBlock::iterator It,
MachineBasicBlock *MBB) const {
diff --git a/llvm/include/llvm/CodeGen/ScheduleDAG.h b/llvm/include/llvm/CodeGen/ScheduleDAG.h
index fe1bbde0d58e9..7711dc479607d 100644
--- a/llvm/include/llvm/CodeGen/ScheduleDAG.h
+++ b/llvm/include/llvm/CodeGen/ScheduleDAG.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/iterator.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/TargetLowering.h"
@@ -743,10 +744,11 @@ class TargetRegisterInfo;
SUnit *ExitSU;
// Have any new nodes been added?
- bool Dirty = false;
+ bool getDirty() const { return Updates.getFlag(0); }
+ void setDirty(bool Value) { Updates.setFlag(0, Value); }
// Outstanding added edges, that have not been applied to the ordering.
- SmallVector<std::pair<SUnit *, SUnit *>, 16> Updates;
+ llvm::SmallVectorWithFlags<std::pair<SUnit *, SUnit *>, 16> Updates;
/// Maps topological index to the node number.
std::vector<int> Index2Node;
@@ -818,7 +820,7 @@ class TargetRegisterInfo;
/// Mark the ordering as temporarily broken, after a new node has been
/// added.
- void MarkDirty() { Dirty = true; }
+ void MarkDirty() { setDirty(true); }
typedef std::vector<int>::iterator iterator;
typedef std::vector<int>::const_iterator const_iterator;
diff --git a/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h b/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
index 7a080dccfb061..60f1b00fb4a71 100644
--- a/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/SparseMultiSet.h"
#include "llvm/CodeGen/LiveRegUnits.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -116,20 +117,24 @@ namespace llvm {
/// True if the DAG builder should remove kill flags (in preparation for
/// rescheduling).
- bool RemoveKillFlags;
+ bool getRemoveKillFlags() const { return Clusters.getFlag(0); }
+ void setRemoveKillFlags(bool Value) { Clusters.setFlag(0, Value); }
/// True if regions with a single MI should be scheduled.
- bool ScheduleSingleMIRegions = false;
+ bool getScheduleSingleMIRegions() const { return Clusters.getFlag(1); }
+ void setScheduleSingleMIRegions(bool Value) { Clusters.setFlag(1, Value); }
/// The standard DAG builder does not normally include terminators as DAG
/// nodes because it does not create the necessary dependencies to prevent
/// reordering. A specialized scheduler can override
/// TargetInstrInfo::isSchedulingBoundary then enable this flag to indicate
/// it has taken responsibility for scheduling the terminator correctly.
- bool CanHandleTerminators = false;
+ bool getCanHandleTerminators() const { return Clusters.getFlag(2); }
+ void setCanHandleTerminators(bool Value) { Clusters.setFlag(2, Value); }
/// Whether lane masks should get tracked.
- bool TrackLaneMasks = false;
+ bool getTrackLaneMasks() const { return Clusters.getFlag(3); }
+ void setTrackLaneMasks(bool Value) { Clusters.setFlag(3, Value); }
// State specific to the current scheduling region.
// ------------------------------------------------
@@ -167,7 +172,10 @@ namespace llvm {
/// Tracks the last instructions in this region using each virtual register.
VReg2SUnitOperIdxMultiMap CurrentVRegUses;
- SmallVector<ClusterInfo> Clusters;
+ llvm::SmallVectorWithFlags<
+ ClusterInfo,
+ llvm::CalculateSmallVectorDefaultInlinedElements<ClusterInfo>::value, 4>
+ Clusters;
friend class ScheduleDAGDependencyBuilder;
@@ -224,7 +232,7 @@ namespace llvm {
/// Whether regions with a single MI should be scheduled.
bool shouldScheduleSingleMIRegions() const {
- return ScheduleSingleMIRegions;
+ return getScheduleSingleMIRegions();
}
/// Returns an iterator to the top of the current scheduling region.
@@ -317,7 +325,7 @@ namespace llvm {
bool addEdge(SUnit *SuccSU, const SDep &PredDep);
/// Returns the array of the clusters.
- SmallVector<ClusterInfo> &getClusters() { return Clusters; }
+ auto &getClusters() { return Clusters; }
/// Get the specific cluster, return nullptr for InvalidClusterId.
ClusterInfo *getCluster(unsigned Idx) {
diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
index cd4c11dfcacec..bd2d399555a78 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/iterator.h"
@@ -1777,6 +1778,11 @@ class SelectionDAG {
/// the final TokenFactor has less than 64k operands.
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL,
SmallVectorImpl<SDValue> &Vals);
+ template <unsigned FlagBits>
+ SDValue getTokenFactor(const SDLoc &DL,
+ SmallVectorWithFlagsImpl<SDValue, FlagBits> &Vals) {
+ return getTokenFactorImpl(DL, Vals);
+ }
/// *Mutate* the specified machine node's memory references to the provided
/// list.
@@ -2779,6 +2785,19 @@ class SelectionDAG {
ArrayRef<SDValue> Scalars);
private:
+ template <typename ValueListT>
+ SDValue getTokenFactorImpl(const SDLoc &DL, ValueListT &Vals) {
+ size_t Limit = SDNode::getMaxNumOperands();
+ while (Vals.size() > Limit) {
+ unsigned SliceIdx = Vals.size() - Limit;
+ auto ExtractedTFs = ArrayRef<SDValue>(Vals).slice(SliceIdx, Limit);
+ SDValue NewTF = getNode(ISD::TokenFactor, DL, MVT::Other, ExtractedTFs);
+ Vals.erase(Vals.begin() + SliceIdx, Vals.end());
+ Vals.emplace_back(NewTF);
+ }
+ return getNode(ISD::TokenFactor, DL, MVT::Other, Vals);
+ }
+
#ifndef NDEBUG
void verifyNode(SDNode *N) const;
#endif
diff --git a/llvm/include/llvm/CodeGen/SwitchLoweringUtils.h b/llvm/include/llvm/CodeGen/SwitchLoweringUtils.h
index 33fa71ae109ea..40b0cda564539 100644
--- a/llvm/include/llvm/CodeGen/SwitchLoweringUtils.h
+++ b/llvm/include/llvm/CodeGen/SwitchLoweringUtils.h
@@ -10,6 +10,7 @@
#define LLVM_CODEGEN_SWITCHLOWERINGUTILS_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/IR/InstrTypes.h"
@@ -220,21 +221,27 @@ struct BitTestBlock {
const Value *SValue;
Register Reg;
MVT RegVT;
- bool Emitted;
- bool ContiguousRange;
+ bool getEmitted() const { return Cases.getFlag(0); }
+ void setEmitted(bool Value) { Cases.setFlag(0, Value); }
+ bool getContiguousRange() const { return Cases.getFlag(1); }
+ void setContiguousRange(bool Value) { Cases.setFlag(1, Value); }
MachineBasicBlock *Parent;
MachineBasicBlock *Default;
- BitTestInfo Cases;
+ llvm::SmallVectorWithFlagsFor<BitTestInfo, 3> Cases;
BranchProbability Prob;
BranchProbability DefaultProb;
- bool FallthroughUnreachable = false;
+ bool getFallthroughUnreachable() const { return Cases.getFlag(2); }
+ bool setFallthroughUnreachable(bool Value) {
+ Cases.setFlag(2, Value);
+ return Value;
+ }
BitTestBlock(APInt F, APInt R, const Value *SV, Register Rg, MVT RgVT, bool E,
bool CR, MachineBasicBlock *P, MachineBasicBlock *D,
BitTestInfo C, BranchProbability Pr)
: First(std::move(F)), Range(std::move(R)), SValue(SV), Reg(Rg),
- RegVT(RgVT), Emitted(E), ContiguousRange(CR), Parent(P), Default(D),
- Cases(std::move(C)), Prob(Pr) {}
+ RegVT(RgVT), Parent(P), Default(D),
+ Cases(unsigned(E) | (unsigned(CR) << 1), std::move(C)), Prob(Pr) {}
};
/// Return the range of values within a range.
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 616ae3e0b7747..877a8a52fba42 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/ISDOpcodes.h"
@@ -4978,10 +4979,11 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
/// described by the Ins array, into the specified DAG. The implementation
/// should fill in the InVals array with legal-type argument values, and
/// return the resulting token chain value.
- virtual SDValue LowerFormalArguments(
- SDValue /*Chain*/, CallingConv::ID /*CallConv*/, bool /*isVarArg*/,
- const SmallVectorImpl<ISD::InputArg> & /*Ins*/, const SDLoc & /*dl*/,
- SelectionDAG & /*DAG*/, SmallVectorImpl<SDValue> & /*InVals*/) const {
+ virtual SDValue
+ LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+ bool /*isVarArg*/, llvm::ArrayRef<ISD::InputArg> /*Ins*/,
+ const SDLoc & /*dl*/, SelectionDAG & /*DAG*/,
+ SmallVectorImpl<SDValue> & /*InVals*/) const {
llvm_unreachable("Not Implemented");
}
@@ -5013,23 +5015,44 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
Type *OrigRetTy = nullptr;
/// Same as OrigRetTy, or partially legalized for soft float libcalls.
Type *RetTy = nullptr;
- bool RetSExt : 1;
- bool RetZExt : 1;
- bool IsVarArg : 1;
- bool IsInReg : 1;
- bool DoesNotReturn : 1;
- bool IsReturnValueUsed : 1;
- bool IsConvergent : 1;
- bool IsPatchPoint : 1;
- bool IsPreallocated : 1;
- bool NoMerge : 1;
+ bool getRetSExt() const { return InVals.getFlag(0); }
+ void setRetSExt(bool Value) { InVals.setFlag(0, Value); }
+ bool getRetZExt() const { return InVals.getFlag(1); }
+ void setRetZExt(bool Value) { InVals.setFlag(1, Value); }
+ bool getIsVarArg() const { return InVals.getFlag(2); }
+ bool setIsVarArg(bool Value) {
+ InVals.setFlag(2, Value);
+ return Value;
+ }
+ bool getIsInReg() const { return InVals.getFlag(3); }
+ void setIsInReg(bool Value) { InVals.setFlag(3, Value); }
+ bool getDoesNotReturn() const { return Ins.getFlag(0); }
+ bool setDoesNotReturn(bool Value) {
+ Ins.setFlag(0, Value);
+ return Value;
+ }
+ bool getIsReturnValueUsed() const { return Ins.getFlag(1); }
+ void setIsReturnValueUsed(bool Value) { Ins.setFlag(1, Value); }
+ bool getIsConvergent() const { return Ins.getFlag(2); }
+ void setIsConvergent(bool Value) { Ins.setFlag(2, Value); }
+ bool getIsPatchPointFlag() const { return Ins.getFlag(3); }
+ void setIsPatchPointFlag(bool Value) { Ins.setFlag(3, Value); }
+ bool getIsPreallocatedFlag() const { return Outs.getFlag(0); }
+ void setIsPreallocatedFlag(bool Value) { Outs.setFlag(0, Value); }
+ bool getNoMerge() const { return Outs.getFlag(1); }
+ void setNoMerge(bool Value) { Outs.setFlag(1, Value); }
// IsTailCall should be modified by implementations of
// TargetLowering::LowerCall that perform tail call conversions.
- bool IsTailCall = false;
+ bool getIsTailCall() const { return Outs.getFlag(2); }
+ bool setIsTailCall(bool Value) {
+ Outs.setFlag(2, Value);
+ return Value;
+ }
// Is Call lowering done post SelectionDAG type legalization.
- bool IsPostTypeLegalization = false;
+ bool getIsPostTypeLegalizationFlag() const { return Outs.getFlag(3); }
+ void setIsPostTypeLegalizationFlag(bool Value) { Outs.setFlag(3, Value); }
unsigned NumFixedArgs = -1;
CallingConv::ID CallConv = CallingConv::C;
@@ -5038,10 +5061,10 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
SelectionDAG &DAG;
SDLoc DL;
const CallBase *CB = nullptr;
- SmallVector<ISD::OutputArg, 32> Outs;
+ llvm::SmallVectorWithFlags<ISD::OutputArg, 32, 4> Outs;
SmallVector<SDValue, 32> OutVals;
- SmallVector<ISD::InputArg, 32> Ins;
- SmallVector<SDValue, 4> InVals;
+ llvm::SmallVectorWithFlags<ISD::InputArg, 32, 4> Ins;
+ llvm::SmallVectorWithFlags<SDValue, 4, 4> InVals;
const ConstantInt *CFIType = nullptr;
SDValue ConvergenceControlToken;
GlobalValue *DeactivationSymbol = nullptr;
@@ -5049,10 +5072,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
std::optional<PtrAuthInfo> PAI;
CallLoweringInfo(SelectionDAG &DAG)
- : RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
- DoesNotReturn(false), IsReturnValueUsed(true), IsConvergent(false),
- IsPatchPoint(false), IsPreallocated(false), NoMerge(false),
- DAG(DAG) {}
+ : DAG(DAG), Ins(decltype(this->Ins)::withFlags(2)) {}
CallLoweringInfo &setDebugLoc(const SDLoc &dl) {
DL = dl;
@@ -5090,10 +5110,10 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
SDValue Target, ArgListTy &&ArgsList,
AttributeSet ResultAttrs = {}) {
RetTy = OrigRetTy = ResultType;
- IsInReg = ResultAttrs.hasAttribute(Attribute::InReg);
- RetSExt = ResultAttrs.hasAttribute(Attribute::SExt);
- RetZExt = ResultAttrs.hasAttribute(Attribute::ZExt);
- NoMerge = ResultAttrs.hasAttribute(Attribute::NoMerge);
+ setIsInReg(ResultAttrs.hasAttribute(Attribute::InReg));
+ setRetSExt(ResultAttrs.hasAttribute(Attribute::SExt));
+ setRetZExt(ResultAttrs.hasAttribute(Attribute::ZExt));
+ setNoMerge(ResultAttrs.hasAttribute(Attribute::NoMerge));
Callee = Target;
CallConv = CC;
@@ -5107,15 +5127,15 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
const CallBase &Call) {
RetTy = OrigRetTy = ResultType;
- IsInReg = Call.hasRetAttr(Attribute::InReg);
- DoesNotReturn =
+ setIsInReg(Call.hasRetAttr(Attribute::InReg));
+ setDoesNotReturn(
Call.doesNotReturn() ||
- (!isa<InvokeInst>(Call) && isa<UnreachableInst>(Call.getNextNode()));
- IsVarArg = FTy->isVarArg();
- IsReturnValueUsed = !Call.use_empty();
- RetSExt = Call.hasRetAttr(Attribute::SExt);
- RetZExt = Call.hasRetAttr(Attribute::ZExt);
- NoMerge = Call.hasFnAttr(Attribute::NoMerge);
+ (!isa<InvokeInst>(Call) && isa<UnreachableInst>(Call.getNextNode())));
+ setIsVarArg(FTy->isVarArg());
+ setIsReturnValueUsed(!Call.use_empty());
+ setRetSExt(Call.hasRetAttr(Attribute::SExt));
+ setRetZExt(Call.hasRetAttr(Attribute::ZExt));
+ setNoMerge(Call.hasFnAttr(Attribute::NoMerge));
Callee = Target;
@@ -5129,52 +5149,52 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
}
CallLoweringInfo &setInRegister(bool Value = true) {
- IsInReg = Value;
+ setIsInReg(Value);
return *this;
}
CallLoweringInfo &setNoReturn(bool Value = true) {
- DoesNotReturn = Value;
+ setDoesNotReturn(Value);
return *this;
}
CallLoweringInfo &setVarArg(bool Value = true) {
- IsVarArg = Value;
+ setIsVarArg(Value);
return *this;
}
CallLoweringInfo &setTailCall(bool Value = true) {
- IsTailCall = Value;
+ setIsTailCall(Value);
return *this;
}
CallLoweringInfo &setDiscardResult(bool Value = true) {
- IsReturnValueUsed = !Value;
+ setIsReturnValueUsed(!Value);
return *this;
}
CallLoweringInfo &setConvergent(bool Value = true) {
- IsConvergent = Value;
+ setIsConvergent(Value);
return *this;
}
CallLoweringInfo &setSExtResult(bool Value = true) {
- RetSExt = Value;
+ setRetSExt(Value);
return *this;
}
CallLoweringInfo &setZExtResult(bool Value = true) {
- RetZExt = Value;
+ setRetZExt(Value);
return *this;
}
CallLoweringInfo &setIsPatchPoint(bool Value = true) {
- IsPatchPoint = Value;
+ setIsPatchPointFlag(Value);
return *this;
}
CallLoweringInfo &setIsPreallocated(bool Value = true) {
- IsPreallocated = Value;
+ setIsPreallocatedFlag(Value);
return *this;
}
@@ -5184,7 +5204,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
}
CallLoweringInfo &setIsPostTypeLegalization(bool Value=true) {
- IsPostTypeLegalization = Value;
+ setIsPostTypeLegalizationFlag(Value);
return *this;
}
@@ -5285,10 +5305,10 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
/// described by the Outs array can fit into the return registers. If false
/// is returned, an sret-demotion is performed.
virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
- MachineFunction &/*MF*/, bool /*isVarArg*/,
- const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
- LLVMContext &/*Context*/, const Type *RetTy) const
- {
+ MachineFunction & /*MF*/, bool /*isVarArg*/,
+ llvm::ArrayRef<ISD::OutputArg> /*Outs*/,
+ LLVMContext & /*Context*/,
+ const Type *RetTy) const {
// Return true by default to get preexisting behavior.
return true;
}
@@ -5302,7 +5322,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
/// return the resulting token chain value.
virtual SDValue LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
bool /*isVarArg*/,
- const SmallVectorImpl<ISD::OutputArg> & /*Outs*/,
+ llvm::ArrayRef<ISD::OutputArg> /*Outs*/,
const SmallVectorImpl<SDValue> & /*OutVals*/,
const SDLoc & /*dl*/,
SelectionDAG & /*DAG*/) const {
diff --git a/llvm/include/llvm/CodeGen/TargetSchedule.h b/llvm/include/llvm/CodeGen/TargetSchedule.h
index eee87c0398abd..d7342993b057c 100644
--- a/llvm/include/llvm/CodeGen/TargetSchedule.h
+++ b/llvm/include/llvm/CodeGen/TargetSchedule.h
@@ -16,6 +16,7 @@
#define LLVM_CODEGEN_TARGETSCHEDULE_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/MC/MCInstrItineraries.h"
@@ -36,7 +37,7 @@ class TargetSchedModel {
const TargetSubtargetInfo *STI = nullptr;
const TargetInstrInfo *TII = nullptr;
- SmallVector<unsigned, 16> ResourceFactors;
+ llvm::SmallVectorWithFlags<unsigned, 16, 2> ResourceFactors;
// Multiply to normalize microops to resource units.
unsigned MicroOpFactor = 0;
@@ -53,8 +54,10 @@ class TargetSchedModel {
// can force preference of the other. By disabling both, we will throw away
// any target specific hardware details for scheduling decisions, and fall
// into things that provide generic info such as defaultDefLatency.
- bool EnableSchedModel = true;
- bool EnableSchedItins = true;
+ bool getEnableSchedModel() const { return !ResourceFactors.getFlag(0); }
+ void setEnableSchedModel(bool Value) { ResourceFactors.setFlag(0, !Value); }
+ bool getEnableSchedItins() const { return !ResourceFactors.getFlag(1); }
+ void setEnableSchedItins(bool Value) { ResourceFactors.setFlag(1, !Value); }
public:
TargetSchedModel() : SchedModel(MCSchedModel::Default) {}
diff --git a/llvm/include/llvm/DTLTO/DTLTO.h b/llvm/include/llvm/DTLTO/DTLTO.h
index 9213a84ff57e5..999e18394e955 100644
--- a/llvm/include/llvm/DTLTO/DTLTO.h
+++ b/llvm/include/llvm/DTLTO/DTLTO.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/ThreadPool.h"
@@ -56,9 +57,11 @@ class LLVM_ABI DTLTO : public LTO {
bool SaveTempsArg)
: Base(std::move(Conf), writeIndexesBackendInstance(),
ParallelCodeGenParallelismLevel, LTOMode),
- AddBuffer(AddBufferArg), SaveTemps(SaveTempsArg),
- ShouldEmitIndexFiles(EmitIndexFiles),
- ShouldEmitImportFiles(EmitImportsFiles), OnIndexWriteCb(OnWrite),
+ AddBuffer(AddBufferArg),
+ Jobs(decltype(this->Jobs)::withFlags(
+ unsigned(SaveTempsArg) | (unsigned(EmitIndexFiles) << 1) |
+ (unsigned(EmitImportsFiles) << 2))),
+ OnIndexWriteCb(OnWrite),
DistributorParams{Distributor, DistributorArgs,
RemoteCompiler, RemoteCompilerPrependArgs,
RemoteCompilerArgs, LinkerOutputFile} {
@@ -138,7 +141,8 @@ class LLVM_ABI DTLTO : public LTO {
// Normalized output directory from LinkerOutputFile.
SString LinkerOutputDir;
// Keep temporary files when true.
- bool SaveTemps = false;
+ bool getSaveTemps() const { return Jobs.getFlag(0); }
+ void setSaveTemps(bool Value) { Jobs.setFlag(0, Value); }
// Saves the content of Buffer to Path overwriting any existing file.
static Error save(StringRef Buffer, StringRef Path);
@@ -168,7 +172,9 @@ class LLVM_ABI DTLTO : public LTO {
private:
// Backend compilation jobs, one per module.
- SmallVector<Job> Jobs;
+ llvm::SmallVectorWithFlags<
+ Job, llvm::CalculateSmallVectorDefaultInlinedElements<Job>::value, 3>
+ Jobs;
// Input module IDs that must be extracted to individual files.
DenseSet<StringRef> InputModuleIDsToExtract;
// Task index offset for first ThinLTO job.
@@ -176,9 +182,11 @@ class LLVM_ABI DTLTO : public LTO {
// Optional cache for native objects.
FileCache Cache;
// Keep summary index files when true.
- bool ShouldEmitIndexFiles = false;
+ bool getShouldEmitIndexFiles() const { return Jobs.getFlag(1); }
+ void setShouldEmitIndexFiles(bool Value) { Jobs.setFlag(1, Value); }
// Keep summary import files when true.
- bool ShouldEmitImportFiles = false;
+ bool getShouldEmitImportFiles() const { return Jobs.getFlag(2); }
+ void setShouldEmitImportFiles(bool Value) { Jobs.setFlag(2, Value); }
// On index file write callback.
IndexWriteCallback OnIndexWriteCb;
diff --git a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
index 4ba1f007b0d00..1e4719061289c 100644
--- a/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
+++ b/llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/AddressRanges.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/AccelTable.h"
#include "llvm/CodeGen/NonRelocatableStringpool.h"
#include "llvm/DWARFLinker/Classic/DWARFLinkerCompileUnit.h"
@@ -256,20 +257,20 @@ class LLVM_ABI DWARFLinker : public DWARFLinkerBase {
/// Verify the input DWARF.
void setVerifyInputDWARF(bool Verify) override {
- Options.VerifyInputDWARF = Verify;
+ Options.setVerifyInputDWARF(Verify);
}
/// Do not unique types according to ODR.
- void setNoODR(bool NoODR) override { Options.NoODR = NoODR; }
+ void setNoODR(bool NoODR) override { Options.setNoODR(NoODR); }
/// Update index tables only(do not modify rest of DWARF).
void setUpdateIndexTablesOnly(bool Update) override {
- Options.Update = Update;
+ Options.setUpdate(Update);
}
/// Set whether to keep the enclosing function for a static variable.
void setKeepFunctionForStatic(bool KeepFunctionForStatic) override {
- Options.KeepFunctionForStatic = KeepFunctionForStatic;
+ Options.setKeepFunctionForStatic(KeepFunctionForStatic);
}
/// Use specified number of threads for parallel files linking.
@@ -807,23 +808,27 @@ class LLVM_ABI DWARFLinker : public DWARFLinkerBase {
bool Statistics = false;
/// Verify the input DWARF.
- bool VerifyInputDWARF = false;
+ bool getVerifyInputDWARF() const { return AccelTables.getFlag(0); }
+ void setVerifyInputDWARF(bool Value) { AccelTables.setFlag(0, Value); }
/// Do not unique types according to ODR
- bool NoODR = false;
+ bool getNoODR() const { return AccelTables.getFlag(1); }
+ void setNoODR(bool Value) { AccelTables.setFlag(1, Value); }
/// Update
- bool Update = false;
+ bool getUpdate() const { return AccelTables.getFlag(2); }
+ void setUpdate(bool Value) { AccelTables.setFlag(2, Value); }
/// Whether we want a static variable to force us to keep its enclosing
/// function.
- bool KeepFunctionForStatic = false;
+ bool getKeepFunctionForStatic() const { return AccelTables.getFlag(3); }
+ void setKeepFunctionForStatic(bool Value) { AccelTables.setFlag(3, Value); }
/// Number of threads.
unsigned Threads = 1;
/// The accelerator table kinds
- SmallVector<AccelTableKind, 1> AccelTables;
+ llvm::SmallVectorWithFlags<AccelTableKind, 1, 4> AccelTables;
/// Prepend path for the clang modules.
std::string PrependPath;
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index f4662aa347088..3a18e447f1100 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -15,6 +15,7 @@
#define LLVM_DEBUGINFO_DICONTEXT_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/WithColor.h"
@@ -209,11 +210,14 @@ struct DIDumpOptions {
bool DisplayRawContents = false;
bool IsEH = false;
bool DumpNonSkeleton = false;
- bool ShowAggregateErrors = false;
- bool PrintRegisterOnly = false;
+ bool showAggregateErrors() const { return FilterChildTag.getFlag(0); }
+ void setShowAggregateErrors(bool Show) { FilterChildTag.setFlag(0, Show); }
+ bool printRegisterOnly() const { return FilterChildTag.getFlag(1); }
+ void setPrintRegisterOnly(bool Print) { FilterChildTag.setFlag(1, Print); }
std::string JsonErrSummaryFile;
/// List of DWARF tags to filter children by.
- llvm::SmallVector<unsigned, 0> FilterChildTag;
+ // Flag bits 0 and 1 enable aggregate errors and register-only printing.
+ llvm::SmallVectorWithFlags<unsigned, 0, 2> FilterChildTag;
std::function<llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)>
GetNameForDWARFReg;
/// The target of the object being dumped.
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
index c510103a448d4..6f41f673f6dd8 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
@@ -10,6 +10,7 @@
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Support/Error.h"
@@ -102,11 +103,12 @@ class DWARFDebugMacro {
// a macinfo[.dwo] section which doesn't have header itself, hence
// for that case other fields in the `Header` are uninitialized.
MacroHeader Header;
- SmallVector<Entry, 4> Macros;
+ llvm::SmallVectorWithFlags<Entry, 4> Macros;
uint64_t Offset;
/// Whether or not this is a .debug_macro section.
- bool IsDebugMacro;
+ bool getIsDebugMacro() const { return Macros.getFlag(0); }
+ void setIsDebugMacro(bool Value) { Macros.setFlag(0, Value); }
};
/// A list of all the macro entries in the debug_macinfo section.
diff --git a/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h
index 2b6a3a6620be8..49e2cf191edef 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h
@@ -9,6 +9,7 @@
#ifndef LLVM_DEBUGINFO_DWARF_LOWLEVEL_DWARFEXPRESSION_H
#define LLVM_DEBUGINFO_DWARF_LOWLEVEL_DWARFEXPRESSION_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -89,10 +90,14 @@ class DWARFExpression {
uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
Description Desc;
- bool Error = false;
+ bool getError() const { return OperandEndOffsets.getFlag(0); }
+ bool setError(bool Value) {
+ OperandEndOffsets.setFlag(0, Value);
+ return Value;
+ }
uint64_t EndOffset;
SmallVector<uint64_t> Operands;
- SmallVector<uint64_t> OperandEndOffsets;
+ llvm::SmallVectorWithFlags<uint64_t> OperandEndOffsets;
public:
const Description &getDescription() const { return Desc; }
@@ -108,7 +113,7 @@ class DWARFExpression {
return OperandEndOffsets[Idx];
}
uint64_t getEndOffset() const { return EndOffset; }
- bool isError() const { return Error; }
+ bool isError() const { return getError(); }
private:
LLVM_ABI bool extract(DataExtractor Data, uint8_t AddressSize,
@@ -126,9 +131,9 @@ class DWARFExpression {
Operation Op;
iterator(const DWARFExpression *Expr, uint64_t Offset)
: Expr(Expr), Offset(Offset) {
- Op.Error =
+ Op.setError(
Offset >= Expr->Data.getData().size() ||
- !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
+ !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format));
}
public:
@@ -137,9 +142,9 @@ class DWARFExpression {
iterator &operator++() {
Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
- Op.Error =
+ Op.setError(
Offset >= Expr->Data.getData().size() ||
- !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
+ !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format));
return *this;
}
diff --git a/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
index 27399d93fe587..4077a5d3f3ea9 100644
--- a/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -17,6 +17,7 @@
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
@@ -114,24 +115,28 @@ class LLVM_ABI ExecutionEngine {
const DataLayout DL;
/// Whether lazy JIT compilation is enabled.
- bool CompilingLazily;
+ bool getCompilingLazily() const { return Modules.getFlag(0); }
+ void setCompilingLazily(bool Value) { Modules.setFlag(0, Value); }
/// Whether JIT compilation of external global variables is allowed.
- bool GVCompilationDisabled;
+ bool getGVCompilationDisabled() const { return Modules.getFlag(1); }
+ void setGVCompilationDisabled(bool Value) { Modules.setFlag(1, Value); }
/// Whether the JIT should perform lookups of external symbols (e.g.,
/// using dlsym).
- bool SymbolSearchingDisabled;
+ bool getSymbolSearchingDisabled() const { return Modules.getFlag(2); }
+ void setSymbolSearchingDisabled(bool Value) { Modules.setFlag(2, Value); }
/// Whether the JIT should verify IR modules during compilation.
- bool VerifyModules;
+ bool getVerifyModulesFlag() const { return Modules.getFlag(3); }
+ void setVerifyModulesFlag(bool Value) { Modules.setFlag(3, Value); }
friend class EngineBuilder; // To allow access to JITCtor and InterpCtor.
protected:
/// The list of Modules that we are JIT'ing from. We use a SmallVector to
/// optimize for the case where there is only one module.
- SmallVector<std::unique_ptr<Module>, 1> Modules;
+ llvm::SmallVectorWithFlags<std::unique_ptr<Module>, 1, 4> Modules;
/// getMemoryforGV - Allocate memory for a global variable.
virtual char *getMemoryForGV(const GlobalVariable *GV);
@@ -457,42 +462,34 @@ class LLVM_ABI ExecutionEngine {
/// (ExecutionEngine::lock) or otherwise ensure that no other thread calls a
/// lazy stub. See http://llvm.org/PR5184 for details.
void DisableLazyCompilation(bool Disabled = true) {
- CompilingLazily = !Disabled;
- }
- bool isCompilingLazily() const {
- return CompilingLazily;
+ setCompilingLazily(!Disabled);
}
+ bool isCompilingLazily() const { return getCompilingLazily(); }
/// DisableGVCompilation - If called, the JIT will abort if it's asked to
/// allocate space and populate a GlobalVariable that is not internal to
/// the module.
void DisableGVCompilation(bool Disabled = true) {
- GVCompilationDisabled = Disabled;
- }
- bool isGVCompilationDisabled() const {
- return GVCompilationDisabled;
+ setGVCompilationDisabled(Disabled);
}
+ bool isGVCompilationDisabled() const { return getGVCompilationDisabled(); }
/// DisableSymbolSearching - If called, the JIT will not try to lookup unknown
/// symbols with dlsym. A client can still use InstallLazyFunctionCreator to
/// resolve symbols in a custom way.
void DisableSymbolSearching(bool Disabled = true) {
- SymbolSearchingDisabled = Disabled;
+ setSymbolSearchingDisabled(Disabled);
}
bool isSymbolSearchingDisabled() const {
- return SymbolSearchingDisabled;
+ return getSymbolSearchingDisabled();
}
/// Enable/Disable IR module verification.
///
/// Note: Module verification is enabled by default in Debug builds, and
/// disabled by default in Release. Use this method to override the default.
- void setVerifyModules(bool Verify) {
- VerifyModules = Verify;
- }
- bool getVerifyModules() const {
- return VerifyModules;
- }
+ void setVerifyModules(bool Verify) { setVerifyModulesFlag(Verify); }
+ bool getVerifyModules() const { return getVerifyModulesFlag(); }
/// InstallLazyFunctionCreator - If an unknown function is needed, the
/// specified function pointer is invoked to create it. If it returns null,
@@ -545,9 +542,11 @@ class EngineBuilder {
std::optional<CodeModel::Model> CMModel;
std::string MArch;
std::string MCPU;
- SmallVector<std::string, 4> MAttrs;
- bool VerifyModules;
- bool EmulatedTLS = true;
+ llvm::SmallVectorWithFlags<std::string, 4, 2> MAttrs;
+ bool getVerifyModulesFlag() const { return MAttrs.getFlag(0); }
+ void setVerifyModulesFlag(bool Value) { MAttrs.setFlag(0, Value); }
+ bool getEmulatedTLSFlag() const { return !MAttrs.getFlag(1); }
+ void setEmulatedTLSFlag(bool Value) { MAttrs.setFlag(1, !Value); }
public:
/// Default constructor for EngineBuilder.
@@ -632,7 +631,7 @@ class EngineBuilder {
/// setVerifyModules - Set whether the JIT implementation should verify
/// IR modules during compilation.
EngineBuilder &setVerifyModules(bool Verify) {
- VerifyModules = Verify;
+ setVerifyModulesFlag(Verify);
return *this;
}
@@ -645,16 +644,16 @@ class EngineBuilder {
}
void setEmulatedTLS(bool EmulatedTLS) {
- this->EmulatedTLS = EmulatedTLS;
+ this->setEmulatedTLSFlag(EmulatedTLS);
}
LLVM_ABI TargetMachine *selectTarget();
/// selectTarget - Pick a target either via -march or by guessing the native
/// arch. Add any CPU features specified via -mcpu or -mattr.
- LLVM_ABI TargetMachine *
- selectTarget(const Triple &TargetTriple, StringRef MArch, StringRef MCPU,
- const SmallVectorImpl<std::string> &MAttrs);
+ LLVM_ABI TargetMachine *selectTarget(const Triple &TargetTriple,
+ StringRef MArch, StringRef MCPU,
+ ArrayRef<std::string> MAttrs);
ExecutionEngine *create() {
return create(selectTarget());
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h
index 5bc8ed7a14dbc..b5f3097b3c032 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Object/ObjectFile.h"
@@ -488,8 +489,12 @@ class LibraryScanner {
SmallVector<StringRef, 2> rpath;
SmallVector<StringRef, 2> runPath;
- SmallVector<StringRef, 4> deps;
- bool isPIE = false;
+ llvm::SmallVectorWithFlags<StringRef, 4> deps;
+ bool getIsPIE() const { return deps.getFlag(0); }
+ bool setIsPIE(bool Value) {
+ deps.setFlag(0, Value);
+ return Value;
+ }
void addRPath(StringRef s) { rpath.push_back(Saver.save(s)); }
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index 047be5cee229a..dc9e92c1ab097 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Frontend/Atomic/Atomic.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPGridValues.h"
@@ -513,8 +514,7 @@ class OpenMPIRBuilder {
/// Create a new OpenMPIRBuilder operating on the given module \p M. This will
/// not have an effect on \p M (see initialize)
OpenMPIRBuilder(Module &M)
- : M(M), Builder(M), OffloadInfoManager(this), T(M.getTargetTriple()),
- IsFinalized(false) {}
+ : M(M), Builder(M), OffloadInfoManager(this), T(M.getTargetTriple()) {}
LLVM_ABI ~OpenMPIRBuilder();
class AtomicInfo : public llvm::AtomicInfo {
@@ -2678,10 +2678,15 @@ class OpenMPIRBuilder {
PostOutlineCBTy PostOutlineCB;
BasicBlock *EntryBB, *ExitBB, *OuterAllocBB;
SmallVector<BasicBlock *> OuterDeallocBBs;
- SmallVector<Value *, 2> ExcludeArgsFromAggregate;
+ llvm::SmallVectorWithFlags<Value *, 2> ExcludeArgsFromAggregate;
SetVector<Value *> Inputs, Outputs;
// TODO: this should be safe to enable by default
- bool FixUpNonEntryAllocas = false;
+ bool getFixUpNonEntryAllocas() const {
+ return ExcludeArgsFromAggregate.getFlag(0);
+ }
+ void setFixUpNonEntryAllocas(bool Value) {
+ ExcludeArgsFromAggregate.setFlag(0, Value);
+ }
virtual ~OutlineInfo() = default;
@@ -2719,7 +2724,7 @@ class OpenMPIRBuilder {
/// Collection of declare target globals to rewrite uses of during
/// device module finalizaiton.
- SmallVector<DeclareTargetGlobalReplacement, 8>
+ llvm::SmallVectorWithFlags<DeclareTargetGlobalReplacement, 8, 2>
DeclareTargetGlobalReplacements;
/// Collection of owned canonical loop objects that eventually need to be
@@ -2985,11 +2990,12 @@ class OpenMPIRBuilder {
/// mappers, and non-contiguous information.
struct MapInfosTy {
struct StructNonContiguousInfo {
- bool IsNonContiguous = false;
+ bool getIsNonContiguous() const { return Strides.getFlag(0); }
+ void setIsNonContiguous(bool Value) { Strides.setFlag(0, Value); }
MapDimArrayTy Dims;
MapNonContiguousArrayTy Offsets;
MapNonContiguousArrayTy Counts;
- MapNonContiguousArrayTy Strides;
+ llvm::SmallVectorWithFlagsFor<MapNonContiguousArrayTy, 1> Strides;
};
MapValuesArrayTy BasePointers;
MapValuesArrayTy Pointers;
@@ -4050,7 +4056,12 @@ class OpenMPIRBuilder {
Value *emitRMWOpAsInstruction(Value *Src1, Value *Src2,
AtomicRMWInst::BinOp RMWOp);
- bool IsFinalized;
+ bool getIsFinalized() const {
+ return DeclareTargetGlobalReplacements.getFlag(0);
+ }
+ void setIsFinalized(bool Value) {
+ DeclareTargetGlobalReplacements.setFlag(0, Value);
+ }
public:
/// a struct to pack relevant information while generating atomic Ops
@@ -4203,13 +4214,18 @@ class OpenMPIRBuilder {
/// \return Insertion point after generated atomic capture IR.
/// Whether to emit special handling for IEEE 754 -0.0 == +0.0 in
/// atomic compare operations on floating-point types.
- bool HandleFPNegZero = false;
+ bool getHandleFPNegZeroFlag() const {
+ return DeclareTargetGlobalReplacements.getFlag(1);
+ }
+ void setHandleFPNegZeroFlag(bool Value) {
+ DeclareTargetGlobalReplacements.setFlag(1, Value);
+ }
/// Set whether atomic compare should handle -0.0/+0.0 equivalence.
/// Returns the previous value so callers can save and restore it.
bool setHandleFPNegZero(bool FPNegZero) {
- bool Old = HandleFPNegZero;
- HandleFPNegZero = FPNegZero;
+ bool Old = getHandleFPNegZeroFlag();
+ setHandleFPNegZeroFlag(FPNegZero);
return Old;
}
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index 64541779e726c..b1b52463c7f1e 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/DebugInfoMetadata.h"
@@ -58,8 +59,8 @@ namespace llvm {
MapVector<MDNode *, SetVector<Metadata *>> AllMacrosPerParent;
/// Track nodes that may be unresolved.
- SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes;
- bool AllowUnresolvedNodes;
+ // Flag bit 0 permits unresolved nodes.
+ SmallVectorWithFlags<TrackingMDNodeRef, 4> UnresolvedNodes;
/// Each subprogram's preserved local and static local variables, labels,
/// imported entities, and types.
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index 934c838782417..55aecfcd50b9b 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
@@ -109,9 +110,6 @@ class DataLayout {
};
private:
- bool BigEndian = false;
- bool VectorsAreElementAligned = false;
-
unsigned AllocaAddrSpace = 0;
unsigned ProgramAddrSpace = 0;
unsigned DefaultGlobalsAddrSpace = 0;
@@ -134,7 +132,8 @@ class DataLayout {
ManglingModeT ManglingMode = MM_None;
// FIXME: `unsigned char` truncates the value parsed by `parseSpecifier`.
- SmallVector<unsigned char, 8> LegalIntWidths;
+ // Flag bits 0 and 1 record big endianness and element-aligned vectors.
+ SmallVectorWithFlags<unsigned char, 8, 2> LegalIntWidths;
/// Primitive type specifications. Sorted and uniqued by type bit width.
SmallVector<PrimitiveSpec, 6> IntSpecs;
@@ -214,11 +213,11 @@ class DataLayout {
LLVM_ABI static Expected<DataLayout> parse(StringRef LayoutString);
/// Layout endianness...
- bool isLittleEndian() const { return !BigEndian; }
- bool isBigEndian() const { return BigEndian; }
+ bool isLittleEndian() const { return !isBigEndian(); }
+ bool isBigEndian() const { return LegalIntWidths.getFlag(0); }
/// Whether vectors are element aligned, rather than naturally aligned.
- bool vectorsAreElementAligned() const { return VectorsAreElementAligned; }
+ bool vectorsAreElementAligned() const { return LegalIntWidths.getFlag(1); }
/// Returns the string representation of the DataLayout.
///
diff --git a/llvm/include/llvm/IR/DroppedVariableStats.h b/llvm/include/llvm/IR/DroppedVariableStats.h
index 8a1dbd6aeb60a..6db9a74b98894 100644
--- a/llvm/include/llvm/IR/DroppedVariableStats.h
+++ b/llvm/include/llvm/IR/DroppedVariableStats.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Compiler.h"
#include <tuple>
@@ -48,14 +49,17 @@ class DroppedVariableStats {
DroppedVariableStats(const DroppedVariableStats &) = delete;
void operator=(const DroppedVariableStats &) = delete;
- bool getPassDroppedVariables() { return PassDroppedVariables; }
+ bool getPassDroppedVariables() { return getPassDroppedVariablesFlag(); }
protected:
LLVM_ABI void setup();
LLVM_ABI void cleanup();
- bool DroppedVariableStatsEnabled = false;
+ bool getDroppedVariableStatsEnabled() const { return InlinedAts.getFlag(0); }
+ void setDroppedVariableStatsEnabled(bool Value) {
+ InlinedAts.setFlag(0, Value);
+ }
struct DebugVariables {
/// DenseSet of VarIDs before an optimization pass has run.
DenseSet<VarID> DebugVariablesBefore;
@@ -73,7 +77,9 @@ class DroppedVariableStats {
/// A stack of DenseMaps, which map the name of an llvm::Function to a
/// DenseMap of VarIDs and their inlinedAt locations before an optimization
/// pass has run.
- SmallVector<DenseMap<StringRef, DenseMap<VarID, DILocation *>>> InlinedAts;
+ SmallVectorWithFlagsFor<
+ SmallVector<DenseMap<StringRef, DenseMap<VarID, DILocation *>>>, 2>
+ InlinedAts;
/// Calculate the number of dropped variables in an llvm::Function or
/// llvm::MachineFunction and print the relevant information to stdout.
LLVM_ABI void calculateDroppedStatsAndPrint(
@@ -129,7 +135,8 @@ class DroppedVariableStats {
bool isInlinedAtChildOfOrEqualTo(const DILocation *InlinedAt,
const DILocation *DbgValInlinedAt);
- bool PassDroppedVariables = false;
+ bool getPassDroppedVariablesFlag() const { return InlinedAts.getFlag(1); }
+ void setPassDroppedVariablesFlag(bool Value) { InlinedAts.setFlag(1, Value); }
};
} // namespace llvm
diff --git a/llvm/include/llvm/IR/LegacyPassManagers.h b/llvm/include/llvm/IR/LegacyPassManagers.h
index d25bcafc9cc05..30cea275545a7 100644
--- a/llvm/include/llvm/IR/LegacyPassManagers.h
+++ b/llvm/include/llvm/IR/LegacyPassManagers.h
@@ -256,7 +256,7 @@ class LLVM_ABI PMTopLevelManager {
// TODO: We could consider sorting the dependency arrays within the
// AnalysisUsage (since they are conceptually unordered).
ID.AddBoolean(AU.getPreservesAll());
- auto ProfileVec = [&](const SmallVectorImpl<AnalysisID>& Vec) {
+ auto ProfileVec = [&](ArrayRef<AnalysisID> Vec) {
ID.AddInteger(Vec.size());
for(AnalysisID AID : Vec)
ID.AddPointer(AID);
@@ -432,7 +432,7 @@ class LLVM_ABI PMDataManager {
private:
void dumpAnalysisUsage(StringRef Msg, const Pass *P,
- const AnalysisUsage::VectorType &Set) const;
+ ArrayRef<AnalysisID> Set) const;
// Set of available Analysis. This information is used while scheduling
// pass. If a pass requires an analysis which is not available then
diff --git a/llvm/include/llvm/IR/PassTimingInfo.h b/llvm/include/llvm/IR/PassTimingInfo.h
index cf2dcd33fdb96..0673ac07b50fb 100644
--- a/llvm/include/llvm/IR/PassTimingInfo.h
+++ b/llvm/include/llvm/IR/PassTimingInfo.h
@@ -16,6 +16,7 @@
#define LLVM_IR_PASSTIMINGINFO_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
@@ -73,15 +74,17 @@ class TimePassesHandler {
SmallVector<Timer *, 8> PassActiveTimerStack;
/// Stack of currently active analysis timers. Analyses can request other
/// analyses.
- SmallVector<Timer *, 8> AnalysisActiveTimerStack;
+ llvm::SmallVectorWithFlags<Timer *, 8, 2> AnalysisActiveTimerStack;
/// Custom output stream to print timing information into.
/// By default (== nullptr) we emit time report into the stream created by
/// CreateInfoOutputFile().
raw_ostream *OutStream = nullptr;
- bool Enabled;
- bool PerRun;
+ bool getEnabled() const { return AnalysisActiveTimerStack.getFlag(0); }
+ void setEnabled(bool Value) { AnalysisActiveTimerStack.setFlag(0, Value); }
+ bool getPerRun() const { return AnalysisActiveTimerStack.getFlag(1); }
+ void setPerRun(bool Value) { AnalysisActiveTimerStack.setFlag(1, Value); }
public:
static constexpr StringRef PassGroupName = "pass";
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index cea66f99b99bb..ed897725614bf 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -15,6 +15,7 @@
#ifndef LLVM_LTO_LTO_H
#define LLVM_LTO_LTO_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/Support/Compiler.h"
@@ -122,7 +123,7 @@ class InputFile {
InputFile() = default;
std::vector<BitcodeModule> Mods;
- SmallVector<char, 0> Strtab;
+ llvm::SmallVectorWithFlags<char, 0, 3> Strtab;
std::vector<Symbol> Symbols;
// [begin, end) for each module
@@ -133,14 +134,17 @@ class InputFile {
std::vector<std::pair<StringRef, Comdat::SelectionKind>> ComdatTable;
MemoryBufferRef MbRef;
- bool IsFatLTOObject = false;
+ bool getIsFatLTOObject() const { return Strtab.getFlag(0); }
+ void setIsFatLTOObject(bool Value) { Strtab.setFlag(0, Value); }
// For distributed compilation, each input must exist as an individual
// bitcode file on disk identified by its ModuleID. For archive members and
// FatLTO objects, the input bitcode is a sub-section of a larger file. In
// these cases we flag that the bitcode must be written to a temporary
// standalone file. Effectively, extracted from its container.
- bool ExtractForDistribution = false;
- bool IsThinLTO = false;
+ bool getExtractForDistributionFlag() const { return Strtab.getFlag(1); }
+ void setExtractForDistributionFlag(bool Value) { Strtab.setFlag(1, Value); }
+ bool getIsThinLTO() const { return Strtab.getFlag(2); }
+ void setIsThinLTO(bool Value) { Strtab.setFlag(2, Value); }
StringRef ArchivePath;
StringRef MemberName;
@@ -215,17 +219,21 @@ class InputFile {
MemoryBufferRef getFileBuffer() const { return MbRef; }
// Returns true if this input should be extracted to disk for distribution.
// See the comment on ExtractForDistribution for details.
- bool getExtractForDistribution() const { return ExtractForDistribution; }
+ bool getExtractForDistribution() const {
+ return getExtractForDistributionFlag();
+ }
// Mark whether this input should be extracted to disk for distribution.
// See the comment on ExtractForDistribution for details.
- void setExtractForDistribution(bool EFD) { ExtractForDistribution = EFD; }
+ void setExtractForDistribution(bool EFD) {
+ setExtractForDistributionFlag(EFD);
+ }
// Returns true if this bitcode came from a FatLTO object.
- bool isFatLTOObject() const { return IsFatLTOObject; }
+ bool isFatLTOObject() const { return getIsFatLTOObject(); }
// Mark this bitcode as coming from a FatLTO object.
- void fatLTOObject(bool FO) { IsFatLTOObject = FO; }
+ void fatLTOObject(bool FO) { setIsFatLTOObject(FO); }
// Returns true if bitcode is ThinLTO.
- bool isThinLTO() const { return IsThinLTO; }
+ bool isThinLTO() const { return getIsThinLTO(); }
// Store an archive path and a member name.
void setArchivePathAndName(StringRef Path, StringRef Name) {
@@ -640,7 +648,10 @@ class LLVM_ABI LTO {
Error checkPartiallySplit();
- mutable bool CalledGetMaxTasks = false;
+ bool getCalledGetMaxTasks() const { return BitcodeLibFuncs.getFlag(0); }
+ void setCalledGetMaxTasks(bool Value) const {
+ BitcodeLibFuncs.setFlag(0, Value);
+ }
protected:
// LTO mode when using Unified LTO.
@@ -672,7 +683,7 @@ class LLVM_ABI LTO {
// LibFuncs that were implemented in bitcode but were not extracted
// from their libraries. Such functions cannot safely be called, since
// they have lost their opportunity to be defined.
- SmallVector<StringRef> BitcodeLibFuncs;
+ mutable llvm::SmallVectorWithFlags<StringRef> BitcodeLibFuncs;
public:
/// Helper to emit an optimization remark during the LTO link when outside of
diff --git a/llvm/include/llvm/MC/DXContainerInfo.h b/llvm/include/llvm/MC/DXContainerInfo.h
index 7f1744034866d..bdf3b4990d3c7 100644
--- a/llvm/include/llvm/MC/DXContainerInfo.h
+++ b/llvm/include/llvm/MC/DXContainerInfo.h
@@ -10,6 +10,7 @@
#define LLVM_MC_DXCONTAINERINFO_H
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/BinaryFormat/DXContainer.h"
namespace llvm {
@@ -128,8 +129,10 @@ struct SourceInfo {
/// modifiable format, and can be used to serialize the data back into valid
/// SourceInfo.
struct SourceInfoBuilder {
- bool IsFilled = false;
- bool IsFinalized = false;
+ bool getIsFilled() const { return Args.getFlag(0); }
+ void setIsFilled(bool Value) { Args.setFlag(0, Value); }
+ bool getIsFinalized() const { return Args.getFlag(1); }
+ void setIsFinalized(bool Value) { Args.setFlag(1, Value); }
SourceInfo BaseData;
SmallString<128> CompressedContents;
@@ -151,7 +154,11 @@ struct SourceInfoBuilder {
private:
std::optional<dxbc::SourceInfo::Contents::CompressionType> CompressionType;
SmallVector<std::pair<StringRef, StringRef>> FileNamesAndContents;
- SmallVector<std::pair<StringRef, StringRef>> Args;
+ llvm::SmallVectorWithFlags<std::pair<StringRef, StringRef>,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ std::pair<StringRef, StringRef>>::value,
+ 2>
+ Args;
void recomputeAfterCompression(uint32_t CompressedSize);
};
diff --git a/llvm/include/llvm/MC/DXContainerPSVInfo.h b/llvm/include/llvm/MC/DXContainerPSVInfo.h
index 0de0fbb36d957..4ab25021ef059 100644
--- a/llvm/include/llvm/MC/DXContainerPSVInfo.h
+++ b/llvm/include/llvm/MC/DXContainerPSVInfo.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/MC/StringTableBuilder.h"
@@ -27,16 +28,28 @@ namespace mcdxbc {
struct PSVSignatureElement {
StringRef Name;
- SmallVector<uint32_t> Indices;
+ llvm::SmallVectorWithFlags<uint32_t> Indices;
uint8_t StartRow;
uint8_t Cols;
uint8_t StartCol;
- bool Allocated;
+ bool getAllocated() const { return Indices.getFlag(0); }
+ void setAllocated(bool Value) { Indices.setFlag(0, Value); }
dxbc::PSV::SemanticKind Kind;
dxbc::PSV::ComponentType Type;
dxbc::PSV::InterpolationMode Mode;
uint8_t DynamicMask;
uint8_t Stream;
+
+ PSVSignatureElement() = default;
+ PSVSignatureElement(StringRef Name, SmallVector<uint32_t> Indices,
+ uint8_t StartRow, uint8_t Cols, uint8_t StartCol,
+ bool Allocated, dxbc::PSV::SemanticKind Kind,
+ dxbc::PSV::ComponentType Type,
+ dxbc::PSV::InterpolationMode Mode, uint8_t DynamicMask,
+ uint8_t Stream)
+ : Name(Name), Indices(unsigned(Allocated), std::move(Indices)),
+ StartRow(StartRow), Cols(Cols), StartCol(StartCol), Kind(Kind),
+ Type(Type), Mode(Mode), DynamicMask(DynamicMask), Stream(Stream) {}
};
// This data structure is a helper for reading and writing PSV RuntimeInfo data.
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 41d082765a468..3d03630ebade6 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
@@ -57,9 +58,12 @@ class MCAssembler {
std::unique_ptr<MCCodeEmitter> Emitter;
std::unique_ptr<MCObjectWriter> Writer;
- bool HasLayout = false;
- bool HasFinalLayout = false;
- bool RelaxAll = false;
+ bool getHasLayout() const { return PendingErrors.getFlag(0); }
+ void setHasLayout(bool Value) { PendingErrors.setFlag(0, Value); }
+ bool getHasFinalLayout() const { return PendingErrors.getFlag(1); }
+ void setHasFinalLayout(bool Value) { PendingErrors.setFlag(1, Value); }
+ bool getRelaxAllFlag() const { return PendingErrors.getFlag(2); }
+ void setRelaxAllFlag(bool Value) { PendingErrors.setFlag(2, Value); }
// Cumulative upstream size change during `relaxOnce`. Used to compensate
// forward-reference displacements in `evaluateFixup`.
@@ -79,7 +83,8 @@ class MCAssembler {
};
SmallVector<RelocDirective, 0> relocDirectives;
- mutable SmallVector<std::pair<SMLoc, std::string>, 0> PendingErrors;
+ mutable llvm::SmallVectorWithFlags<std::pair<SMLoc, std::string>, 0, 3>
+ PendingErrors;
MCDwarfLineTableParams LTParams;
@@ -196,10 +201,10 @@ class MCAssembler {
// Layout all section and prepare them for emission.
LLVM_ABI void layout();
- bool hasLayout() const { return HasLayout; }
- bool hasFinalLayout() const { return HasFinalLayout; }
- bool getRelaxAll() const { return RelaxAll; }
- void setRelaxAll(bool Value) { RelaxAll = Value; }
+ bool hasLayout() const { return getHasLayout(); }
+ bool hasFinalLayout() const { return getHasFinalLayout(); }
+ bool getRelaxAll() const { return getRelaxAllFlag(); }
+ void setRelaxAll(bool Value) { setRelaxAllFlag(Value); }
int64_t getStretch() const { return Stretch; }
bool isBundlingEnabled() const { return bool(BundleAlign); }
diff --git a/llvm/include/llvm/MC/MCCodeView.h b/llvm/include/llvm/MC/MCCodeView.h
index 7f871f6816dbb..ea409e541bda8 100644
--- a/llvm/include/llvm/MC/MCCodeView.h
+++ b/llvm/include/llvm/MC/MCCodeView.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <deque>
@@ -254,7 +255,7 @@ class CodeViewContext {
};
/// Array storing added file information.
- SmallVector<FileInfo, 4> Files;
+ llvm::SmallVectorWithFlags<FileInfo, 4> Files;
/// The offset of the first and last .cv_loc directive for a given function
/// id.
@@ -268,7 +269,8 @@ class CodeViewContext {
/// Indicate whether we have already laid out the checksum table addresses or
/// not.
- bool ChecksumOffsetsAssigned = false;
+ bool getChecksumOffsetsAssigned() const { return Files.getFlag(0); }
+ void setChecksumOffsetsAssigned(bool Value) { Files.setFlag(0, Value); }
/// Append-only storage of MCCVDefRangeFragment::Ranges.
std::deque<SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 0>>
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 7e76abe08f56f..28888636e10ef 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -186,13 +187,14 @@ class MCContext {
/// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to
/// catch errors if .secure_log_unique appears twice without
/// .secure_log_reset appearing between them.
- bool SecureLogUsed = false;
/// The compilation directory to use for DW_AT_comp_dir.
SmallString<128> CompilationDir;
/// Prefix replacement map for source file information.
- SmallVector<std::pair<std::string, std::string>, 0> DebugPrefixMap;
+ // Flag bits 0-3 record secure logging, temporary names, reset, and errors.
+ SmallVectorWithFlags<std::pair<std::string, std::string>, 0, 4>
+ DebugPrefixMap;
/// The main file name if passed in explicitly.
std::string MainFileName;
@@ -239,7 +241,6 @@ class MCContext {
/// differences between temporary and non-temporary labels (primarily on
/// Darwin).
bool SaveTempLabels = false;
- bool UseNamesOnTempLabels = false;
/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID = 0;
@@ -324,9 +325,6 @@ class MCContext {
SpecificBumpPtrAllocator<MCSubtargetInfo> MCSubtargetAllocator;
/// Do automatic reset in destructor
- bool AutoReset;
-
- bool HadError = false;
void reportCommon(SMLoc Loc,
std::function<void(SMDiagnostic &, const SourceMgr *)>);
@@ -418,7 +416,7 @@ class MCContext {
LLVM_ABI CodeViewContext &getCVContext();
- void setUseNamesOnTempLabels(bool Value) { UseNamesOnTempLabels = Value; }
+ void setUseNamesOnTempLabels(bool Value) { DebugPrefixMap.setFlag(1, Value); }
/// \name Module Lifetime Management
/// @{
@@ -725,7 +723,7 @@ class MCContext {
return getMCDwarfLineTable(CUID).getMCDwarfFiles();
}
- const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) {
+ ArrayRef<std::string> getMCDwarfDirs(unsigned CUID = 0) {
return getMCDwarfLineTable(CUID).getMCDwarfDirs();
}
@@ -822,8 +820,8 @@ class MCContext {
SecureLog = std::move(Value);
}
- bool getSecureLogUsed() { return SecureLogUsed; }
- void setSecureLogUsed(bool Value) { SecureLogUsed = Value; }
+ bool getSecureLogUsed() { return DebugPrefixMap.getFlag(0); }
+ void setSecureLogUsed(bool Value) { DebugPrefixMap.setFlag(0, Value); }
void *allocate(unsigned Size, unsigned Align = 8) {
return Allocator.Allocate(Size, Align);
@@ -837,7 +835,7 @@ class MCContext {
return StringSaver(Allocator).save(s);
}
- bool hadError() { return HadError; }
+ bool hadError() { return DebugPrefixMap.getFlag(3); }
LLVM_ABI void diagnose(const SMDiagnostic &SMD);
LLVM_ABI void reportError(SMLoc L, const Twine &Msg);
LLVM_ABI void reportWarning(SMLoc L, const Twine &Msg);
diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h
index 3534a4f349331..7d9b923214570 100644
--- a/llvm/include/llvm/MC/MCDwarf.h
+++ b/llvm/include/llvm/MC/MCDwarf.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/StringTableBuilder.h"
@@ -277,18 +278,16 @@ struct MCDwarfLineTableParams {
struct MCDwarfLineTableHeader {
MCSymbol *Label = nullptr;
- SmallVector<std::string, 3> MCDwarfDirs;
+ // Flag bits 0, 1 and 2 record sources, missing MD5s, and present MD5s.
+ SmallVectorWithFlags<std::string, 3, 3> MCDwarfDirs;
SmallVector<MCDwarfFile, 3> MCDwarfFiles;
StringMap<unsigned> SourceIdMap;
std::string CompilationDir;
MCDwarfFile RootFile;
- bool HasAnySource = false;
-
-private:
- bool HasAllMD5 = true;
- bool HasAnyMD5 = false;
-
-public:
+ bool hasAnySource() const { return MCDwarfDirs.getFlag(0); }
+ void trackSource(bool HasSource) {
+ MCDwarfDirs.setFlag(0, hasAnySource() || HasSource);
+ }
MCDwarfLineTableHeader() = default;
LLVM_ABI Expected<unsigned> tryGetFile(StringRef &Directory,
@@ -305,15 +304,16 @@ struct MCDwarfLineTableHeader {
ArrayRef<char> SpecialOpcodeLengths,
std::optional<MCDwarfLineStr> &LineStr) const;
void resetMD5Usage() {
- HasAllMD5 = true;
- HasAnyMD5 = false;
+ MCDwarfDirs.setFlag(1, false);
+ MCDwarfDirs.setFlag(2, false);
}
void trackMD5Usage(bool MD5Used) {
- HasAllMD5 &= MD5Used;
- HasAnyMD5 |= MD5Used;
+ MCDwarfDirs.setFlag(1, MCDwarfDirs.getFlag(1) || !MD5Used);
+ MCDwarfDirs.setFlag(2, MCDwarfDirs.getFlag(2) || MD5Used);
}
bool isMD5UsageConsistent() const {
- return MCDwarfFiles.empty() || (HasAllMD5 == HasAnyMD5);
+ return MCDwarfFiles.empty() ||
+ (!MCDwarfDirs.getFlag(1) == MCDwarfDirs.getFlag(2));
}
void setRootFile(StringRef Directory, StringRef FileName,
@@ -325,7 +325,7 @@ struct MCDwarfLineTableHeader {
RootFile.Checksum = Checksum;
RootFile.Source = Source;
trackMD5Usage(Checksum.has_value());
- HasAnySource |= Source.has_value();
+ trackSource(Source.has_value());
}
void resetFileTable() {
@@ -333,7 +333,7 @@ struct MCDwarfLineTableHeader {
MCDwarfFiles.clear();
RootFile.Name.clear();
resetMD5Usage();
- HasAnySource = false;
+ MCDwarfDirs.setFlag(0, false);
}
private:
@@ -411,7 +411,7 @@ class MCDwarfLineTable {
Header.RootFile.Checksum = Checksum;
Header.RootFile.Source = Source;
Header.trackMD5Usage(Checksum.has_value());
- Header.HasAnySource |= Source.has_value();
+ Header.trackSource(Source.has_value());
}
void resetFileTable() { Header.resetFileTable(); }
@@ -432,11 +432,9 @@ class MCDwarfLineTable {
Header.Label = Label;
}
- const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
- return Header.MCDwarfDirs;
- }
+ ArrayRef<std::string> getMCDwarfDirs() const { return Header.MCDwarfDirs; }
- SmallVectorImpl<std::string> &getMCDwarfDirs() {
+ SmallVectorWithFlagsImpl<std::string, 3> &getMCDwarfDirs() {
return Header.MCDwarfDirs;
}
diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h
index acd3570016265..9daa05adb71ab 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -10,6 +10,7 @@
#define LLVM_MC_MCELFSTREAMER_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectStreamer.h"
@@ -38,7 +39,7 @@ class LLVM_ABI MCELFStreamer : public MCObjectStreamer {
/// state management
void reset() override {
- SeenIdent = false;
+ setSeenIdent(false);
MCObjectStreamer::reset();
}
@@ -97,11 +98,12 @@ class LLVM_ABI MCELFStreamer : public MCObjectStreamer {
/// ELF object attributes subsection support
struct AttributeSubSection {
- bool IsActive;
+ bool getIsActive() const { return Content.getFlag(0); }
+ void setIsActive(bool Value) { Content.setFlag(0, Value); }
StringRef VendorName;
unsigned IsOptional;
unsigned ParameterType;
- SmallVector<AttributeItem, 64> Content;
+ llvm::SmallVectorWithFlags<AttributeItem, 64> Content;
};
// Attributes that are added and managed entirely by target.
@@ -115,6 +117,7 @@ class LLVM_ABI MCELFStreamer : public MCObjectStreamer {
void emitAttributesSection(StringRef Vendor, const Twine &Section,
unsigned Type, MCSection *&AttributeSection) {
createAttributesSection(Vendor, Section, Type, AttributeSection, Contents);
+ Contents.clear();
}
void
emitAttributesSection(MCSection *&AttributeSection, const Twine &Section,
@@ -126,16 +129,16 @@ class LLVM_ABI MCELFStreamer : public MCObjectStreamer {
private:
AttributeItem *getAttributeItem(unsigned Attribute);
- size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) const;
+ size_t calculateContentSize(ArrayRef<AttributeItem> AttrsVec) const;
void createAttributesSection(StringRef Vendor, const Twine &Section,
unsigned Type, MCSection *&AttributeSection,
- SmallVector<AttributeItem, 64> &AttrsVec);
+ ArrayRef<AttributeItem> AttrsVec);
void createAttributesWithSubsection(
MCSection *&AttributeSection, const Twine &Section, unsigned Type,
SmallVector<AttributeSubSection, 64> &SubSectionVec);
// GNU attributes that will get emitted at the end of the asm file.
- SmallVector<AttributeItem, 64> GNUAttributes;
+ llvm::SmallVectorWithFlags<AttributeItem, 64> GNUAttributes;
MCBoundaryAlignFragment *BundleBA = nullptr;
public:
@@ -150,7 +153,8 @@ class LLVM_ABI MCELFStreamer : public MCObjectStreamer {
const MCSymbolRefExpr *&S);
void finalizeCGProfile();
- bool SeenIdent = false;
+ bool getSeenIdent() const { return GNUAttributes.getFlag(0); }
+ void setSeenIdent(bool Value) { GNUAttributes.setFlag(0, Value); }
};
LLVM_ABI MCELFStreamer *
diff --git a/llvm/include/llvm/MC/MCInstPrinter.h b/llvm/include/llvm/MC/MCInstPrinter.h
index c615d01493989..ea2f7ee8e5ac2 100644
--- a/llvm/include/llvm/MC/MCInstPrinter.h
+++ b/llvm/include/llvm/MC/MCInstPrinter.h
@@ -9,7 +9,7 @@
#ifndef LLVM_MC_MCINSTPRINTER_H
#define LLVM_MC_MCINSTPRINTER_H
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -72,12 +72,13 @@ class LLVM_ABI MCInstPrinter {
/// If true, a branch immediate (e.g. bl 4) will be printed as a hexadecimal
/// address (e.g. bl 0x20004). This is useful for a stream disassembler
/// (llvm-objdump -d).
- bool PrintBranchImmAsAddress = false;
+ bool getPrintBranchImmAsAddress() const { return ColorStack.getFlag(0); }
/// If true, symbolize branch target and memory reference operands.
- bool SymbolizeOperands = false;
+ bool getSymbolizeOperands() const { return ColorStack.getFlag(1); }
- SmallVector<raw_ostream::Colors, 4> ColorStack{raw_ostream::Colors::RESET};
+ SmallVectorWithFlags<raw_ostream::Colors, 4, 2> ColorStack{
+ raw_ostream::Colors::RESET};
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
@@ -165,11 +166,9 @@ class LLVM_ABI MCInstPrinter {
void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; }
- void setPrintBranchImmAsAddress(bool Value) {
- PrintBranchImmAsAddress = Value;
- }
+ void setPrintBranchImmAsAddress(bool Value) { ColorStack.setFlag(0, Value); }
- void setSymbolizeOperands(bool Value) { SymbolizeOperands = Value; }
+ void setSymbolizeOperands(bool Value) { ColorStack.setFlag(1, Value); }
void setMCInstrAnalysis(const MCInstrAnalysis *Value) { MIA = Value; }
/// Utility function to print immediates in decimal or hex.
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index 7f5875c90d215..bfd38cad6b218 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
@@ -39,9 +40,12 @@ class raw_pwrite_stream;
/// implementation.
class LLVM_ABI MCObjectStreamer : public MCStreamer {
std::unique_ptr<MCAssembler> Assembler;
- bool EmitEHFrame;
- bool EmitDebugFrame;
- bool EmitSFrame;
+ bool getEmitEHFrame() const { return FragStorage.getFlag(0); }
+ void setEmitEHFrame(bool Value) { FragStorage.setFlag(0, Value); }
+ bool getEmitDebugFrame() const { return FragStorage.getFlag(1); }
+ void setEmitDebugFrame(bool Value) { FragStorage.setFlag(1, Value); }
+ bool getEmitSFrame() const { return FragStorage.getFlag(2); }
+ void setEmitSFrame(bool Value) { FragStorage.setFlag(2, Value); }
struct PendingAssignment {
MCSymbol *Symbol;
@@ -53,7 +57,7 @@ class LLVM_ABI MCObjectStreamer : public MCStreamer {
DenseMap<const MCSymbol *, SmallVector<PendingAssignment, 1>>
pendingAssignments;
- SmallVector<std::unique_ptr<uint8_t[]>, 0> FragStorage;
+ llvm::SmallVectorWithFlags<std::unique_ptr<uint8_t[]>, 0, 4> FragStorage;
// Available bytes in the current block for trailing data or new fragments.
size_t FragSpace = 0;
// Used to allocate special fragments that do not use MCFragment's fixed-size
@@ -68,7 +72,8 @@ class LLVM_ABI MCObjectStreamer : public MCStreamer {
protected:
// Within .bundle_lock/.bundle_unlock. A section cannot be switched while a
// group is open, so no per-section state is needed.
- bool BundleLocked = false;
+ bool getBundleLocked() const { return FragStorage.getFlag(3); }
+ void setBundleLocked(bool Value) { FragStorage.setFlag(3, Value); }
MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
std::unique_ptr<MCObjectWriter> OW,
@@ -93,7 +98,7 @@ class LLVM_ABI MCObjectStreamer : public MCStreamer {
MCAssembler &getAssembler() { return *Assembler; }
MCAssembler *getAssemblerPtr() override;
- bool isBundleLocked() const { return BundleLocked; }
+ bool isBundleLocked() const { return getBundleLocked(); }
/// \name MCStreamer Interface
/// @{
diff --git a/llvm/include/llvm/MC/MCObjectWriter.h b/llvm/include/llvm/MC/MCObjectWriter.h
index 54a8f8236f6e4..77b7a509fca85 100644
--- a/llvm/include/llvm/MC/MCObjectWriter.h
+++ b/llvm/include/llvm/MC/MCObjectWriter.h
@@ -9,6 +9,7 @@
#ifndef LLVM_MC_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Compiler.h"
#include "llvm/TargetParser/Triple.h"
@@ -35,12 +36,11 @@ class LLVM_ABI MCObjectWriter {
protected:
MCAssembler *Asm = nullptr;
/// List of declared file names
- SmallVector<std::pair<std::string, size_t>, 0> FileNames;
+ // Flag bits 0 and 1 record addrsig and subsections-via-symbols emission.
+ SmallVectorWithFlags<std::pair<std::string, size_t>, 0, 2> FileNames;
// XCOFF specific: Optional compiler version.
std::string CompilerVersion;
std::vector<const MCSymbol *> AddrsigSyms;
- bool EmitAddrsigSection = false;
- bool SubsectionsViaSymbols = false;
struct CGProfileEntry {
const MCSymbolRefExpr *From;
@@ -106,9 +106,9 @@ class LLVM_ABI MCObjectWriter {
/// Tell the object writer to emit an address-significance table during
/// writeObject(). If this function is not called, all symbols are treated as
/// address-significant.
- void emitAddrsigSection() { EmitAddrsigSection = true; }
+ void emitAddrsigSection() { FileNames.setFlag(0, true); }
- bool getEmitAddrsigSection() { return EmitAddrsigSection; }
+ bool getEmitAddrsigSection() { return FileNames.getFlag(0); }
/// Record the given symbol in the address-significance table to be written
/// diring writeObject().
@@ -118,8 +118,8 @@ class LLVM_ABI MCObjectWriter {
SmallVector<CGProfileEntry, 0> &getCGProfile() { return CGProfile; }
// Mach-O specific: Whether .subsections_via_symbols is enabled.
- bool getSubsectionsViaSymbols() const { return SubsectionsViaSymbols; }
- void setSubsectionsViaSymbols(bool Value) { SubsectionsViaSymbols = Value; }
+ bool getSubsectionsViaSymbols() const { return FileNames.getFlag(1); }
+ void setSubsectionsViaSymbols(bool Value) { FileNames.setFlag(1, Value); }
/// Write the object file and returns the number of bytes written.
///
diff --git a/llvm/include/llvm/MC/MCParser/AsmLexer.h b/llvm/include/llvm/MC/MCParser/AsmLexer.h
index 6ab484565c0d4..5308978643471 100644
--- a/llvm/include/llvm/MC/MCParser/AsmLexer.h
+++ b/llvm/include/llvm/MC/MCParser/AsmLexer.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmMacro.h"
@@ -42,7 +43,8 @@ class AsmCommentConsumer {
class AsmLexer {
/// The current token, stored in the base class for faster access.
- SmallVector<AsmToken, 1> CurTok;
+ // Flag bit 0 selects the MASM default radix.
+ SmallVectorWithFlags<AsmToken, 1> CurTok;
const char *CurPtr = nullptr;
/// NULL-terminated buffer. NULL terminator must reside at `CurBuf.end()`.
@@ -68,7 +70,6 @@ class AsmLexer {
bool LexMasmIntegers = false;
bool LexMasmStrings = false;
bool LexMotorolaIntegers = false;
- bool UseMasmDefaultRadix = false;
unsigned DefaultRadix = 10;
bool LexHLASMIntegers = false;
bool LexHLASMStrings = false;
@@ -168,7 +169,7 @@ class AsmLexer {
/// 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; }
+ void useMasmDefaultRadix(bool V) { CurTok.setFlag(0, V); }
unsigned getMasmDefaultRadix() const { return DefaultRadix; }
void setMasmDefaultRadix(unsigned Radix) { DefaultRadix = Radix; }
diff --git a/llvm/include/llvm/MC/MCParser/MCAsmParser.h b/llvm/include/llvm/MC/MCParser/MCAsmParser.h
index da5ef08381aed..0109a3c73cd3c 100644
--- a/llvm/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/llvm/include/llvm/MC/MCParser/MCAsmParser.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmMacro.h"
@@ -144,17 +145,24 @@ class LLVM_ABI MCAsmParser {
SourceMgr &SrcMgr;
const MCAsmInfo &MAI;
AsmLexer Lexer;
- SmallVector<MCPendingError, 0> PendingErrors;
+ llvm::SmallVectorWithFlags<MCPendingError, 0, 3> PendingErrors;
/// Flag tracking whether any errors have been encountered.
- bool HadError = false;
+ bool getHadError() const { return PendingErrors.getFlag(0); }
+ void setHadError(bool Value) { PendingErrors.setFlag(0, Value); }
- bool ShowParsedOperands = false;
+ bool getShowParsedOperandsFlag() const { return PendingErrors.getFlag(1); }
+ void setShowParsedOperandsFlag(bool Value) {
+ PendingErrors.setFlag(1, Value);
+ }
/// Flag tracking whether we're only interested in symbols, which allows us to
/// avoid some work (e.g. resolving .incbin directives).
// TODO: Adopt this in more places.
- bool SymbolScanningMode = false;
+ bool getSymbolScanningModeFlag() const { return PendingErrors.getFlag(2); }
+ void setSymbolScanningModeFlag(bool Value) {
+ PendingErrors.setFlag(2, Value);
+ }
public:
MCAsmParser(const MCAsmParser &) = delete;
@@ -178,10 +186,10 @@ class LLVM_ABI MCAsmParser {
virtual unsigned getAssemblerDialect() { return 0;}
virtual void setAssemblerDialect(unsigned i) { }
- bool getShowParsedOperands() const { return ShowParsedOperands; }
- void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
+ bool getShowParsedOperands() const { return getShowParsedOperandsFlag(); }
+ void setShowParsedOperands(bool Value) { setShowParsedOperandsFlag(Value); }
- void setSymbolScanningMode(bool Value) { SymbolScanningMode = Value; }
+ void setSymbolScanningMode(bool Value) { setSymbolScanningModeFlag(Value); }
/// Run the parser on the input source buffer.
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
diff --git a/llvm/include/llvm/MCA/Instruction.h b/llvm/include/llvm/MCA/Instruction.h
index e5b2b8ec3d1b6..df5f2569ea577 100644
--- a/llvm/include/llvm/MCA/Instruction.h
+++ b/llvm/include/llvm/MCA/Instruction.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/MC/MCRegister.h" // definition of MCPhysReg.
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
@@ -502,7 +503,8 @@ class InstructionBase {
// This field is set for instructions that are candidates for move
// elimination. For more information about move elimination, see the
// definition of RegisterMappingTracker in RegisterFile.h
- bool IsOptimizableMove;
+ bool getIsOptimizableMove() const { return Uses.getFlag(0); }
+ void setIsOptimizableMove(bool Value) { Uses.setFlag(0, Value); }
// Output dependencies.
// One entry per each implicit and explicit register definition.
@@ -510,7 +512,7 @@ class InstructionBase {
// Input dependencies.
// One entry per each implicit and explicit register use.
- SmallVector<ReadState, 4> Uses;
+ llvm::SmallVectorWithFlags<ReadState, 4> Uses;
// List of operands which can be used by mca::CustomBehaviour
std::vector<MCAOperand> Operands;
@@ -532,12 +534,12 @@ class InstructionBase {
public:
InstructionBase(const InstrDesc &D, const unsigned Opcode)
- : Desc(D), IsOptimizableMove(false), Operands(0), Opcode(Opcode),
- IsALoadBarrier(false), IsAStoreBarrier(false) {}
+ : Desc(D), Operands(0), Opcode(Opcode), IsALoadBarrier(false),
+ IsAStoreBarrier(false) {}
SmallVectorImpl<WriteState> &getDefs() { return Defs; }
ArrayRef<WriteState> getDefs() const { return Defs; }
- SmallVectorImpl<ReadState> &getUses() { return Uses; }
+ SmallVectorWithFlagsImpl<ReadState> &getUses() { return Uses; }
ArrayRef<ReadState> getUses() const { return Uses; }
const InstrDesc &getDesc() const { return Desc; }
@@ -575,9 +577,9 @@ class InstructionBase {
}
// Returns true if this instruction is a candidate for move elimination.
- bool isOptimizableMove() const { return IsOptimizableMove; }
- void setOptimizableMove() { IsOptimizableMove = true; }
- void clearOptimizableMove() { IsOptimizableMove = false; }
+ bool isOptimizableMove() const { return getIsOptimizableMove(); }
+ void setOptimizableMove() { setIsOptimizableMove(true); }
+ void clearOptimizableMove() { setIsOptimizableMove(false); }
bool isMemOp() const { return MayLoad || MayStore; }
// Getters and setters for general instruction flags.
diff --git a/llvm/include/llvm/ObjCopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h
index 1f984f68c6287..f51c513631fb9 100644
--- a/llvm/include/llvm/ObjCopy/CommonConfig.h
+++ b/llvm/include/llvm/ObjCopy/CommonConfig.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ELFTypes.h"
@@ -232,8 +233,9 @@ struct CommonConfig {
SmallVector<NewSectionInfo, 0> AddSection;
SmallVector<StringRef, 0> DumpSection;
SmallVector<NewSectionInfo, 0> UpdateSection;
- SmallVector<SectionPatternAddressUpdate, 0> ChangeSectionAddress;
- SmallVector<StringRef, 0> ExtractSection;
+ llvm::SmallVectorWithFlags<SectionPatternAddressUpdate, 0, 3>
+ ChangeSectionAddress;
+ llvm::SmallVectorWithFlags<StringRef, 0, 4> ExtractSection;
// Section matchers
NameMatcher KeepSection;
@@ -258,31 +260,58 @@ struct CommonConfig {
StringMap<StringRef> SymbolsToRename;
// Symbol info specified by --add-symbol option.
- SmallVector<NewSymbolInfo, 0> SymbolsToAdd;
+ llvm::SmallVectorWithFlags<NewSymbolInfo, 0, 4> SymbolsToAdd;
// Integer options
int64_t ChangeSectionLMAValAll = 0;
// Boolean options
- bool DeterministicArchives = true;
- bool ExtractDWO = false;
- bool ExtractMainPartition = false;
- bool OnlyKeepDebug = false;
- bool PreserveDates = false;
- bool StripAll = false;
- bool StripAllGNU = false;
- bool StripDWO = false;
- bool StripDebug = false;
- bool StripNonAlloc = false;
- bool StripSections = false;
- bool StripUnneeded = false;
- bool Verbose = false;
- bool Weaken = false;
- bool DecompressDebugSections = false;
+ bool getDeterministicArchives() const { return !compressSections.getFlag(0); }
+ void setDeterministicArchives(bool Value) {
+ compressSections.setFlag(0, !Value);
+ }
+ bool getExtractDWO() const { return compressSections.getFlag(1); }
+ void setExtractDWO(bool Value) { compressSections.setFlag(1, Value); }
+ bool getExtractMainPartition() const { return compressSections.getFlag(2); }
+ void setExtractMainPartition(bool Value) {
+ compressSections.setFlag(2, Value);
+ }
+ bool getOnlyKeepDebug() const { return compressSections.getFlag(3); }
+ void setOnlyKeepDebug(bool Value) { compressSections.setFlag(3, Value); }
+ bool getPreserveDates() const { return SymbolsToAdd.getFlag(0); }
+ void setPreserveDates(bool Value) { SymbolsToAdd.setFlag(0, Value); }
+ bool getStripAll() const { return SymbolsToAdd.getFlag(1); }
+ bool setStripAll(bool Value) {
+ SymbolsToAdd.setFlag(1, Value);
+ return Value;
+ }
+ bool getStripAllGNU() const { return SymbolsToAdd.getFlag(2); }
+ void setStripAllGNU(bool Value) { SymbolsToAdd.setFlag(2, Value); }
+ bool getStripDWO() const { return SymbolsToAdd.getFlag(3); }
+ void setStripDWO(bool Value) { SymbolsToAdd.setFlag(3, Value); }
+ bool getStripDebug() const { return ExtractSection.getFlag(0); }
+ void setStripDebug(bool Value) { ExtractSection.setFlag(0, Value); }
+ bool getStripNonAlloc() const { return ExtractSection.getFlag(1); }
+ void setStripNonAlloc(bool Value) { ExtractSection.setFlag(1, Value); }
+ bool getStripSections() const { return ExtractSection.getFlag(2); }
+ void setStripSections(bool Value) { ExtractSection.setFlag(2, Value); }
+ bool getStripUnneeded() const { return ExtractSection.getFlag(3); }
+ void setStripUnneeded(bool Value) { ExtractSection.setFlag(3, Value); }
+ bool getVerbose() const { return ChangeSectionAddress.getFlag(0); }
+ void setVerbose(bool Value) { ChangeSectionAddress.setFlag(0, Value); }
+ bool getWeaken() const { return ChangeSectionAddress.getFlag(1); }
+ void setWeaken(bool Value) { ChangeSectionAddress.setFlag(1, Value); }
+ bool getDecompressDebugSections() const {
+ return ChangeSectionAddress.getFlag(2);
+ }
+ void setDecompressDebugSections(bool Value) {
+ ChangeSectionAddress.setFlag(2, Value);
+ }
DebugCompressionType CompressionType = DebugCompressionType::None;
- SmallVector<std::pair<NameMatcher, llvm::DebugCompressionType>, 0>
+ llvm::SmallVectorWithFlags<std::pair<NameMatcher, llvm::DebugCompressionType>,
+ 0, 4>
compressSections;
// ErrorCallback is used to handle recoverable errors. An Error returned
diff --git a/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
index 01a8762cfb9c3..43e470f32e53b 100644
--- a/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
+++ b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
@@ -9,6 +9,7 @@
#ifndef LLVM_OBJCOPY_ELF_ELFCONFIG_H
#define LLVM_OBJCOPY_ELF_ELFCONFIG_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ObjCopy/CommonConfig.h"
#include "llvm/Object/ELFTypes.h"
@@ -33,13 +34,17 @@ struct ELFConfig {
// --change-start is used.
std::function<uint64_t(uint64_t)> EntryExpr;
- bool AllowBrokenLinks = false;
- bool KeepFileSymbols = false;
- bool LocalizeHidden = false;
- bool VerifyNoteSections = true;
+ bool getAllowBrokenLinks() const { return NotesToRemove.getFlag(0); }
+ void setAllowBrokenLinks(bool Value) { NotesToRemove.setFlag(0, Value); }
+ bool getKeepFileSymbols() const { return NotesToRemove.getFlag(1); }
+ void setKeepFileSymbols(bool Value) { NotesToRemove.setFlag(1, Value); }
+ bool getLocalizeHidden() const { return NotesToRemove.getFlag(2); }
+ void setLocalizeHidden(bool Value) { NotesToRemove.setFlag(2, Value); }
+ bool getVerifyNoteSections() const { return !NotesToRemove.getFlag(3); }
+ void setVerifyNoteSections(bool Value) { NotesToRemove.setFlag(3, !Value); }
// Notes specified by --remove-note option.
- SmallVector<RemoveNoteInfo, 0> NotesToRemove;
+ llvm::SmallVectorWithFlags<RemoveNoteInfo, 0, 4> NotesToRemove;
};
} // namespace objcopy
diff --git a/llvm/include/llvm/Object/MachO.h b/llvm/include/llvm/Object/MachO.h
index cafd6ed3fa9f2..528ca3f6654a5 100644
--- a/llvm/include/llvm/Object/MachO.h
+++ b/llvm/include/llvm/Object/MachO.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -111,7 +112,8 @@ class ExportEntry {
unsigned ParentStringLength = 0;
bool IsExportNode = false;
};
- using NodeList = SmallVector<NodeState, 16>;
+ // Flag bit 0 marks the end of the export traversal.
+ using NodeList = SmallVectorWithFlags<NodeState, 16>;
using node_iterator = NodeList::const_iterator;
Error *E;
@@ -119,7 +121,6 @@ class ExportEntry {
ArrayRef<uint8_t> Trie;
SmallString<256> CumulativeString;
NodeList Stack;
- bool Done = false;
iterator_range<node_iterator> nodes() const { return Stack; }
};
@@ -767,7 +768,7 @@ class LLVM_ABI MachOObjectFile : public ObjectFile {
llvm::binaryformat::Swift5ReflectionSectionKind
mapReflectionSectionNameToEnumValue(StringRef SectionName) const override;
- bool hasPageZeroSegment() const { return HasPageZeroSegment; }
+ bool hasPageZeroSegment() const { return getHasPageZeroSegment(); }
size_t getMachOFilesetEntryOffset() const { return MachOFilesetEntryOffset; }
@@ -858,7 +859,7 @@ class LLVM_ABI MachOObjectFile : public ObjectFile {
SectionList Sections;
using LibraryList = SmallVector<const char*, 1>;
LibraryList Libraries;
- LoadCommandList LoadCommands;
+ llvm::SmallVectorWithFlagsFor<LoadCommandList, 1> LoadCommands;
using LibraryShortName = SmallVector<StringRef, 1>;
using BuildToolList = SmallVector<const char*, 1>;
BuildToolList BuildTools;
@@ -873,7 +874,8 @@ class LLVM_ABI MachOObjectFile : public ObjectFile {
const char *DyldChainedFixupsLoadCmd = nullptr;
const char *DyldExportsTrieLoadCmd = nullptr;
const char *UuidLoadCmd = nullptr;
- bool HasPageZeroSegment = false;
+ bool getHasPageZeroSegment() const { return LoadCommands.getFlag(0); }
+ void setHasPageZeroSegment(bool Value) { LoadCommands.setFlag(0, Value); }
size_t MachOFilesetEntryOffset = 0;
};
diff --git a/llvm/include/llvm/Object/OffloadBundle.h b/llvm/include/llvm/Object/OffloadBundle.h
index 0996d74d71ce4..f1c77a3673c51 100644
--- a/llvm/include/llvm/Object/OffloadBundle.h
+++ b/llvm/include/llvm/Object/OffloadBundle.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
@@ -94,17 +95,20 @@ class OffloadBundleFatBin {
uint64_t Size = 0u;
StringRef FileName;
uint64_t NumberOfEntries;
- bool Decompressed;
- SmallVector<OffloadBundleEntry> Entries;
+ bool getDecompressed() const { return Entries.getFlag(0); }
+ void setDecompressed(bool Value) { Entries.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<OffloadBundleEntry> Entries;
public:
std::unique_ptr<MemoryBuffer> DecompressedBuffer;
- SmallVector<OffloadBundleEntry> getEntries() { return Entries; }
+ SmallVector<OffloadBundleEntry> getEntries() {
+ return {Entries.begin(), Entries.end()};
+ }
uint64_t getSize() const { return Size; }
StringRef getFileName() const { return FileName; }
uint64_t getNumEntries() const { return NumberOfEntries; }
- bool isDecompressed() const { return Decompressed; }
+ bool isDecompressed() const { return getDecompressed(); }
LLVM_ABI static Expected<std::unique_ptr<OffloadBundleFatBin>>
create(MemoryBufferRef, uint64_t SectionOffset, StringRef FileName,
@@ -126,8 +130,8 @@ class OffloadBundleFatBin {
OffloadBundleFatBin(MemoryBufferRef Source, StringRef File,
bool Decompress = false)
- : FileName(File), NumberOfEntries(0), Decompressed(Decompress),
- Entries(SmallVector<OffloadBundleEntry>()) {
+ : FileName(File), NumberOfEntries(0),
+ Entries(decltype(this->Entries)::withFlags(unsigned(Decompress))) {
if (Decompress)
DecompressedBuffer =
MemoryBuffer::getMemBufferCopy(Source.getBuffer(), File);
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 1d3e044bbb22f..f6ba733b3a779 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -15,6 +15,7 @@
#ifndef LLVM_OBJECTYAML_DXCONTAINERYAML_H
#define LLVM_OBJECTYAML_DXCONTAINERYAML_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/DXContainer.h"
@@ -221,17 +222,22 @@ struct SignatureElement {
: Name(StringTable.substr(El.NameOffset,
StringTable.find('\0', El.NameOffset) -
El.NameOffset)),
- Indices(IdxTable.slice(El.IndicesOffset, El.Rows)),
+ Indices(decltype(this->Indices)::withFlags(
+ unsigned(bool(El.Allocated != 0)),
+ IdxTable.slice(El.IndicesOffset, El.Rows))),
StartRow(El.StartRow), Cols(El.Cols), StartCol(El.StartCol),
- Allocated(El.Allocated != 0), Kind(El.Kind), Type(El.Type),
- Mode(El.Mode), DynamicMask(El.DynamicMask), Stream(El.Stream) {}
+ Kind(El.Kind), Type(El.Type), Mode(El.Mode),
+ DynamicMask(El.DynamicMask), Stream(El.Stream) {}
StringRef Name;
- SmallVector<uint32_t> Indices;
+ llvm::SmallVectorWithFlags<uint32_t> Indices;
uint8_t StartRow;
uint8_t Cols;
uint8_t StartCol;
- bool Allocated;
+ bool getAllocatedFlag() const { return Indices.getFlag(0); }
+ void setAllocatedFlag(bool Value) { Indices.setFlag(0, Value); }
+ bool isAllocated() const { return getAllocatedFlag(); }
+ void setAllocated(bool Value) { setAllocatedFlag(Value); }
dxbc::PSV::SemanticKind Kind;
dxbc::PSV::ComponentType Type;
diff --git a/llvm/include/llvm/Option/OptTable.h b/llvm/include/llvm/Option/OptTable.h
index b61ae77f64a34..51fb8249e3991 100644
--- a/llvm/include/llvm/Option/OptTable.h
+++ b/llvm/include/llvm/Option/OptTable.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringTable.h"
#include "llvm/Option/OptSpecifier.h"
@@ -188,7 +189,8 @@ class LLVM_ABI OptTable {
ArrayRef<InfoExtra> InfoExtrasTable;
- bool IgnoreCase;
+ bool getIgnoreCase() const { return PrefixesUnion.getFlag(0); }
+ void setIgnoreCase(bool Value) { PrefixesUnion.setFlag(0, Value); }
/// The subcommand information table.
ArrayRef<SubCommand> SubCommands;
@@ -200,8 +202,8 @@ class LLVM_ABI OptTable {
ValuesCodeFnTy ValuesCodeFn = nullptr;
- bool GroupedShortOptions = false;
- bool DashDashParsing = false;
+ bool getGroupedShortOptionsFlag() const { return PrefixesUnion.getFlag(1); }
+ bool getDashDashParsingFlag() const { return PrefixesUnion.getFlag(2); }
const char *EnvVar = nullptr;
unsigned InputOptionID = 0;
@@ -213,7 +215,7 @@ class LLVM_ABI OptTable {
/// The union of all option prefixes. If an argument does not begin with
/// one of these, it is an input.
- SmallVector<StringRef> PrefixesUnion;
+ SmallVectorWithFlagsFor<SmallVector<StringRef>, 3> PrefixesUnion;
/// The union of the first element of all option prefixes.
SmallString<8> PrefixChars;
@@ -346,11 +348,11 @@ class LLVM_ABI OptTable {
void setInitialOptionsFromEnvironment(const char *E) { EnvVar = E; }
/// Support grouped short options. e.g. -ab represents -a -b.
- void setGroupedShortOptions(bool Value) { GroupedShortOptions = Value; }
+ void setGroupedShortOptions(bool Value) { PrefixesUnion.setFlag(1, Value); }
/// Set whether "--" stops option parsing and treats all subsequent arguments
/// as positional. E.g. -- -a -b gives two positional inputs.
- void setDashDashParsing(bool Value) { DashDashParsing = Value; }
+ void setDashDashParsing(bool Value) { PrefixesUnion.setFlag(2, Value); }
/// Find possible value for given flags. This is used for shell
/// autocompletion.
diff --git a/llvm/include/llvm/PassAnalysisSupport.h b/llvm/include/llvm/PassAnalysisSupport.h
index e81c0c4642d20..f3f4bea7c5075 100644
--- a/llvm/include/llvm/PassAnalysisSupport.h
+++ b/llvm/include/llvm/PassAnalysisSupport.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <tuple>
@@ -57,10 +58,9 @@ class AnalysisUsage {
SmallVector<AnalysisID, 8> Required;
SmallVector<AnalysisID, 2> RequiredTransitive;
SmallVector<AnalysisID, 2> Preserved;
- SmallVector<AnalysisID, 0> Used;
- bool PreservesAll = false;
-
- void pushUnique(VectorType &Set, AnalysisID ID) {
+ /// Flag bit 0 records whether all analyses are preserved.
+ SmallVectorWithFlags<AnalysisID, 0> Used;
+ template <typename VectorT> void pushUnique(VectorT &Set, AnalysisID ID) {
if (!llvm::is_contained(Set, ID))
Set.push_back(ID);
}
@@ -128,10 +128,10 @@ class AnalysisUsage {
LLVM_ABI AnalysisUsage &addPreserved(StringRef Arg);
/// Set by analyses that do not transform their input at all
- void setPreservesAll() { PreservesAll = true; }
+ void setPreservesAll() { Used.setFlag(0, true); }
/// Determine whether a pass said it does not transform its input at all
- bool getPreservesAll() const { return PreservesAll; }
+ bool getPreservesAll() const { return Used.getFlag(0); }
/// This function should be called by the pass, iff they do not:
///
@@ -147,7 +147,7 @@ class AnalysisUsage {
return RequiredTransitive;
}
const VectorType &getPreservedSet() const { return Preserved; }
- const VectorType &getUsedSet() const { return Used; }
+ ArrayRef<AnalysisID> getUsedSet() const { return Used; }
};
//===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/ProfileData/DataAccessProf.h b/llvm/include/llvm/ProfileData/DataAccessProf.h
index ea256ef7b170b..47bf621808f77 100644
--- a/llvm/include/llvm/ProfileData/DataAccessProf.h
+++ b/llvm/include/llvm/ProfileData/DataAccessProf.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/Allocator.h"
@@ -68,8 +69,9 @@ struct SourceLocationRef {
struct DataAccessProfRecordRef {
DataAccessProfRecordRef(uint64_t SymbolID, uint64_t AccessCount,
bool IsStringLiteral)
- : SymbolID(SymbolID), AccessCount(AccessCount),
- IsStringLiteral(IsStringLiteral) {}
+ : SymbolID(SymbolID), AccessCount(AccessCount) {
+ Locations.setFlag(0, IsStringLiteral);
+ }
// Represents a data symbol. The semantic comes in two forms: a symbol index
// for symbol name if `IsStringLiteral` is false, or the hash of a string
@@ -85,10 +87,10 @@ struct DataAccessProfRecordRef {
// True iff this is a record for string literal (symbols with name pattern
// `.str.*` in the symbol table). Required.
- bool IsStringLiteral;
+ bool isStringLiteral() const { return Locations.getFlag(0); }
// The locations of data in the source code. Optional.
- llvm::SmallVector<SourceLocationRef, 0> Locations;
+ llvm::SmallVectorWithFlags<SourceLocationRef, 0> Locations;
};
} // namespace internal
diff --git a/llvm/include/llvm/ProfileData/GCOV.h b/llvm/include/llvm/ProfileData/GCOV.h
index 62ca92b2887b5..0c28e9ffed862 100644
--- a/llvm/include/llvm/ProfileData/GCOV.h
+++ b/llvm/include/llvm/ProfileData/GCOV.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
@@ -203,11 +204,12 @@ class GCOVFile {
StringMap<unsigned> filenameToIdx;
public:
- bool GCNOInitialized = false;
+ bool getGCNOInitialized() const { return functions.getFlag(0); }
+ void setGCNOInitialized(bool Value) { functions.setFlag(0, Value); }
GCOV::GCOVVersion version{};
uint32_t checksum = 0;
StringRef cwd;
- SmallVector<std::unique_ptr<GCOVFunction>, 16> functions;
+ llvm::SmallVectorWithFlags<std::unique_ptr<GCOVFunction>, 16> functions;
std::map<uint32_t, GCOVFunction *> identToFunction;
uint32_t runCount = 0;
uint32_t programCount = 0;
@@ -316,7 +318,7 @@ class GCOVBlock {
LLVM_ABI static uint64_t
augmentOneCycle(GCOVBlock *src,
std::vector<std::pair<GCOVBlock *, size_t>> &stack);
- LLVM_ABI static uint64_t getCyclesCount(const BlockVector &blocks);
+ LLVM_ABI static uint64_t getCyclesCount(ArrayRef<const GCOVBlock *> blocks);
public:
uint32_t number;
diff --git a/llvm/include/llvm/ProfileData/InstrProfWriter.h b/llvm/include/llvm/ProfileData/InstrProfWriter.h
index 73fb9432597cf..5278274cc380e 100644
--- a/llvm/include/llvm/ProfileData/InstrProfWriter.h
+++ b/llvm/include/llvm/ProfileData/InstrProfWriter.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/Object/BuildID.h"
@@ -42,7 +43,8 @@ class InstrProfWriter {
using ProfilingData = SmallDenseMap<uint64_t, InstrProfRecord>;
private:
- bool Sparse;
+ bool getSparse() const { return TemporalProfTraces.getFlag(0); }
+ void setSparse(bool Value) { TemporalProfTraces.setFlag(0, Value); }
StringMap<ProfilingData> FunctionData;
/// The maximum length of a single temporal profile trace.
uint64_t MaxTemporalProfTraceLength;
@@ -51,7 +53,11 @@ class InstrProfWriter {
/// The total number of temporal profile traces seen.
uint64_t TemporalProfTraceStreamSize = 0;
/// The list of temporal profile traces.
- SmallVector<TemporalProfTraceTy> TemporalProfTraces;
+ llvm::SmallVectorWithFlags<TemporalProfTraceTy,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ TemporalProfTraceTy>::value,
+ 4>
+ TemporalProfTraces;
std::mt19937 RNG;
// The MemProf data.
@@ -73,16 +79,27 @@ class InstrProfWriter {
// new vtable names section and header fields.
// TODO: Consider enabling this with future version changes as well, to ease
// deployment of newer versions of llvm-profdata.
- bool WritePrevVersion = false;
+ bool getWritePrevVersion() const { return TemporalProfTraces.getFlag(1); }
+ void setWritePrevVersion(bool Value) { TemporalProfTraces.setFlag(1, Value); }
// The MemProf version we should write.
memprof::IndexedVersion MemProfVersionRequested;
// Whether to serialize the full schema.
- bool MemProfFullSchema;
+ bool getMemProfFullSchemaFlag() const {
+ return TemporalProfTraces.getFlag(2);
+ }
+ void setMemProfFullSchemaFlag(bool Value) {
+ TemporalProfTraces.setFlag(2, Value);
+ }
// Whether to generated random memprof hotness for testing.
- bool MemprofGenerateRandomHotness;
+ bool getMemprofGenerateRandomHotness() const {
+ return TemporalProfTraces.getFlag(3);
+ }
+ void setMemprofGenerateRandomHotness(bool Value) {
+ TemporalProfTraces.setFlag(3, Value);
+ }
std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData;
@@ -90,6 +107,10 @@ class InstrProfWriter {
// to the writer.
memprof::MemProfSummaryBuilder MemProfSumBuilder;
+ template <typename TraceVectorT>
+ void addTemporalProfileTracesImpl(TraceVectorT &SrcTraces,
+ uint64_t SrcStreamSize);
+
public:
// For memprof testing, random hotness can be assigned to the contexts if
// MemprofGenerateRandomHotness is enabled.
@@ -219,7 +240,7 @@ class InstrProfWriter {
void setMemProfVersionRequested(memprof::IndexedVersion Version) {
MemProfVersionRequested = Version;
}
- void setMemProfFullSchema(bool Full) { MemProfFullSchema = Full; }
+ void setMemProfFullSchema(bool Full) { setMemProfFullSchemaFlag(Full); }
// Compute the overlap b/w this object and Other. Program level result is
// stored in Overlap and function level result is stored in FuncLevelOverlap.
diff --git a/llvm/include/llvm/ProfileData/MemProfReader.h b/llvm/include/llvm/ProfileData/MemProfReader.h
index 8fdae7a472d5f..70a1e5bfc05b7 100644
--- a/llvm/include/llvm/ProfileData/MemProfReader.h
+++ b/llvm/include/llvm/ProfileData/MemProfReader.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
@@ -143,8 +144,8 @@ class LLVM_ABI RawMemProfReader final : public MemProfReader {
llvm::SmallVectorImpl<SegmentEntry> &Seg,
llvm::MapVector<uint64_t, MemInfoBlock> &Prof,
CallStackMap &SM, bool KeepName = false)
- : SegmentInfo(Seg.begin(), Seg.end()), CallstackProfileData(Prof),
- StackMap(SM), KeepSymbolName(KeepName) {
+ : SegmentInfo(unsigned(KeepName), Seg.begin(), Seg.end()),
+ CallstackProfileData(Prof), StackMap(SM) {
// We don't call initialize here since there is no raw profile to read. The
// test should pass in the raw profile as structured data.
@@ -158,7 +159,9 @@ class LLVM_ABI RawMemProfReader final : public MemProfReader {
private:
RawMemProfReader(object::OwningBinary<object::Binary> &&Bin, bool KeepName)
- : Binary(std::move(Bin)), KeepSymbolName(KeepName) {}
+ : Binary(std::move(Bin)),
+ SegmentInfo(
+ decltype(this->SegmentInfo)::withFlags(unsigned(KeepName))) {}
// Initializes the RawMemProfReader with the contents in `DataBuffer`.
Error initialize(std::unique_ptr<MemoryBuffer> DataBuffer);
// Read and parse the contents of the `DataBuffer` as a binary format profile.
@@ -195,7 +198,7 @@ class LLVM_ABI RawMemProfReader final : public MemProfReader {
// The memory mapped segment information for all executable segments in the
// profiled binary (filtered from the raw profile using the build id).
- llvm::SmallVector<SegmentEntry, 2> SegmentInfo;
+ llvm::SmallVectorWithFlags<SegmentEntry, 2> SegmentInfo;
// A map from callstack id (same as key in CallStackMap below) to the heap
// information recorded for that allocation context.
@@ -206,7 +209,8 @@ class LLVM_ABI RawMemProfReader final : public MemProfReader {
llvm::DenseMap<uint64_t, llvm::SmallVector<FrameId>> SymbolizedFrame;
// Whether to keep the symbol name for each frame after hashing.
- bool KeepSymbolName = false;
+ bool getKeepSymbolName() const { return SegmentInfo.getFlag(0); }
+ void setKeepSymbolName(bool Value) { SegmentInfo.setFlag(0, Value); }
// A mapping of the hash to symbol name, only used if KeepSymbolName is true.
llvm::DenseMap<uint64_t, std::string> GuidToSymbolName;
};
diff --git a/llvm/include/llvm/ProfileData/SampleProfWriter.h b/llvm/include/llvm/ProfileData/SampleProfWriter.h
index b785d73020de0..e3f2defb15e59 100644
--- a/llvm/include/llvm/ProfileData/SampleProfWriter.h
+++ b/llvm/include/llvm/ProfileData/SampleProfWriter.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/Eytzinger.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/SampleProf.h"
@@ -315,7 +316,7 @@ class LLVM_ABI SampleProfileWriterExtBinaryBase
// Set to use MD5 to represent string in NameTable.
void setUseMD5() override {
- UseMD5 = true;
+ setUseMD5Flag(true);
addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagMD5Name);
// MD5 will be stored as plain uint64_t instead of variable-length
// quantity format in NameTable section.
@@ -339,9 +340,9 @@ class LLVM_ABI SampleProfileWriterExtBinaryBase
resetSecLayout(SectionLayout::CtxSplitLayout);
}
- void setUseMD5ProfileSymbolList() override { UseMD5ProfSymList = true; }
+ void setUseMD5ProfileSymbolList() override { setUseMD5ProfSymList(true); }
- void setUseMD5IndexedTables() override { UseMD5IndexedTables = true; }
+ void setUseMD5IndexedTables() override { setUseMD5IndexedTablesFlag(true); }
/// Select composite encoding for subsequent writes. Composite output
/// requires CompositeProfileVersion or newer when write() is called.
@@ -359,7 +360,8 @@ class LLVM_ABI SampleProfileWriterExtBinaryBase
}
#endif
SecLayout = SL;
- SectionHdrLayout = ExtBinaryHdrLayoutTable[SL];
+ SectionHdrLayout.assign(ExtBinaryHdrLayoutTable[SL].begin(),
+ ExtBinaryHdrLayoutTable[SL].end());
}
protected:
@@ -417,8 +419,9 @@ class LLVM_ABI SampleProfileWriterExtBinaryBase
// 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];
+ llvm::SmallVectorWithFlags<SecHdrTableEntry, 8, 3> SectionHdrLayout{
+ ExtBinaryHdrLayoutTable[DefaultLayout].begin(),
+ ExtBinaryHdrLayoutTable[DefaultLayout].end()};
// 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
@@ -455,13 +458,20 @@ class LLVM_ABI SampleProfileWriterExtBinaryBase
// SecLBRProfile section. It is used to load function profile on demand.
MapVector<SampleContext, uint64_t> FuncOffsetTable;
// Whether to use MD5 to represent string.
- bool UseMD5 = false;
+ bool getUseMD5Flag() const { return SectionHdrLayout.getFlag(0); }
+ void setUseMD5Flag(bool Value) { SectionHdrLayout.setFlag(0, Value); }
// Whether to write the profile symbol list as 64-bit MD5 hashes in Eytzinger
// layout.
- bool UseMD5ProfSymList = false;
+ bool getUseMD5ProfSymList() const { return SectionHdrLayout.getFlag(1); }
+ void setUseMD5ProfSymList(bool Value) { SectionHdrLayout.setFlag(1, Value); }
// Whether to write MD5-based indexed NameTable and parallel FuncOffsetTable
// in Eytzinger layout.
- bool UseMD5IndexedTables = false;
+ bool getUseMD5IndexedTablesFlag() const {
+ return SectionHdrLayout.getFlag(2);
+ }
+ void setUseMD5IndexedTablesFlag(bool Value) {
+ SectionHdrLayout.setFlag(2, Value);
+ }
size_t NumNested = 0;
size_t NumFlat = 0;
diff --git a/llvm/include/llvm/SandboxIR/Tracker.h b/llvm/include/llvm/SandboxIR/Tracker.h
index 881d4cb9d8d64..fe6ccb15845f8 100644
--- a/llvm/include/llvm/SandboxIR/Tracker.h
+++ b/llvm/include/llvm/SandboxIR/Tracker.h
@@ -50,6 +50,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StableHashing.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
@@ -467,14 +468,20 @@ class Tracker {
#ifndef NDEBUG
/// One checker per nested snapshot.
- SmallVector<IRSnapshotChecker> SnapshotChecker;
+ llvm::SmallVectorWithFlags<IRSnapshotChecker> SnapshotChecker;
#endif
public:
#ifndef NDEBUG
/// Helps catch bugs where we are creating new change objects while in the
/// middle of creating other change objects.
- bool InMiddleOfCreatingChange = false;
+ bool getInMiddleOfCreatingChange() const {
+ return SnapshotChecker.getFlag(0);
+ }
+ bool setInMiddleOfCreatingChange(bool Value) {
+ SnapshotChecker.setFlag(0, Value);
+ return Value;
+ }
#endif // NDEBUG
explicit Tracker(Context &Ctx) : Ctx(Ctx) {}
@@ -488,15 +495,15 @@ class Tracker {
void track(std::unique_ptr<IRChangeBase> &&Change) {
assert(State == TrackerState::Record && "The tracker should be tracking!");
#ifndef NDEBUG
- assert(!InMiddleOfCreatingChange &&
+ assert(!getInMiddleOfCreatingChange() &&
"We are in the middle of creating another change!");
if (isTracking())
- InMiddleOfCreatingChange = true;
+ setInMiddleOfCreatingChange(true);
#endif // NDEBUG
Changes.push_back(std::move(Change));
#ifndef NDEBUG
- InMiddleOfCreatingChange = false;
+ setInMiddleOfCreatingChange(false);
#endif
}
/// A convenience wrapper for `track()` that constructs and tracks the Change
diff --git a/llvm/include/llvm/Support/CFGDiff.h b/llvm/include/llvm/Support/CFGDiff.h
index f81215ed71bd4..33e59c37ce2a5 100644
--- a/llvm/include/llvm/Support/CFGDiff.h
+++ b/llvm/include/llvm/Support/CFGDiff.h
@@ -15,6 +15,7 @@
#define LLVM_SUPPORT_CFGDIFF_H
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/CFGUpdate.h"
@@ -64,12 +65,12 @@ template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
// to apply these updates as given. If UpdatedAreReverseApplied is set, the
// updates will be applied in reverse: deleted edges are considered re-added
// and inserted edges are considered deleted when returning children.
- bool UpdatedAreReverseApplied;
+ bool updatesAreReverseApplied() const { return LegalizedUpdates.getFlag(0); }
// Keep the list of legalized updates for a deterministic order of updates
// when using a GraphDiff for incremental updates in the DominatorTree.
// The list is kept in reverse to allow popping from end.
- SmallVector<cfg::Update<NodePtr>, 4> LegalizedUpdates;
+ SmallVectorWithFlags<cfg::Update<NodePtr>, 4> LegalizedUpdates;
void printMap(raw_ostream &OS, const UpdateMapType &M) const {
StringRef DIText[2] = {"Delete", "Insert"};
@@ -89,7 +90,7 @@ template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
}
public:
- GraphDiff() : UpdatedAreReverseApplied(false) {}
+ GraphDiff() = default;
GraphDiff(ArrayRef<cfg::Update<NodePtr>> Updates,
bool ReverseApplyUpdates = false) {
cfg::LegalizeUpdates<NodePtr>(Updates, LegalizedUpdates, InverseGraph);
@@ -99,7 +100,7 @@ template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
Succ[U.getFrom()].DI[IsInsert].push_back(U.getTo());
Pred[U.getTo()].DI[IsInsert].push_back(U.getFrom());
}
- UpdatedAreReverseApplied = ReverseApplyUpdates;
+ LegalizedUpdates.setFlag(0, ReverseApplyUpdates);
}
auto getLegalizedUpdates() const {
@@ -112,7 +113,7 @@ template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
assert(!LegalizedUpdates.empty() && "No updates to apply!");
auto U = LegalizedUpdates.pop_back_val();
unsigned IsInsert =
- (U.getKind() == cfg::UpdateKind::Insert) == !UpdatedAreReverseApplied;
+ (U.getKind() == cfg::UpdateKind::Insert) == !updatesAreReverseApplied();
auto &SuccDIList = Succ[U.getFrom()];
auto &SuccList = SuccDIList.DI[IsInsert];
assert(SuccList.back() == U.getTo());
diff --git a/llvm/include/llvm/Support/CFGUpdate.h b/llvm/include/llvm/Support/CFGUpdate.h
index 18c34bb73695a..9da55330072a9 100644
--- a/llvm/include/llvm/Support/CFGUpdate.h
+++ b/llvm/include/llvm/Support/CFGUpdate.h
@@ -59,9 +59,8 @@ template <typename NodePtr> class Update {
// them when traversing CFG.
// b) It optimizes away updates that cancel each other out, as the end result
// is the same.
-template <typename NodePtr>
-void LegalizeUpdates(ArrayRef<Update<NodePtr>> AllUpdates,
- SmallVectorImpl<Update<NodePtr>> &Result,
+template <typename NodePtr, typename VectorT>
+void LegalizeUpdates(ArrayRef<Update<NodePtr>> AllUpdates, VectorT &Result,
bool InverseGraph, bool ReverseResultOrder = false) {
// Count the total number of inserions of each edge.
// Each insertion adds 1 and deletion subtracts 1. The end number should be
diff --git a/llvm/include/llvm/Support/DebugCounter.h b/llvm/include/llvm/Support/DebugCounter.h
index ce690a86e1081..cbef09d9704aa 100644
--- a/llvm/include/llvm/Support/DebugCounter.h
+++ b/llvm/include/llvm/Support/DebugCounter.h
@@ -45,6 +45,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
@@ -63,16 +64,26 @@ class DebugCounter {
/// Whether counting should be enabled, either due to -debug-counter or
/// -print-debug-counter.
- bool Active = false;
+ bool getActive() const { return Chunks.getFlag(0); }
+ bool setActive(bool Value) {
+ Chunks.setFlag(0, Value);
+ return Value;
+ }
/// Whether chunks for the counter are set (differs from Active in that
/// -print-debug-counter uses Active=true, IsSet=false).
- bool IsSet = false;
+ bool getIsSet() const { return Chunks.getFlag(1); }
+ bool setIsSet(bool Value) {
+ Chunks.setFlag(1, Value);
+ return Value;
+ }
int64_t Count = 0;
uint64_t CurrChunkIdx = 0;
StringRef Name;
StringRef Desc;
- IntegerInclusiveIntervalUtils::IntervalList Chunks;
+ llvm::SmallVectorWithFlagsFor<IntegerInclusiveIntervalUtils::IntervalList,
+ 2>
+ Chunks;
public:
CounterInfo(StringRef Name, StringRef Desc) : Name(Name), Desc(Desc) {
@@ -80,8 +91,8 @@ class DebugCounter {
}
void reset() {
- Active = false;
- IsSet = false;
+ setActive(false);
+ setIsSet(false);
Count = 0;
CurrChunkIdx = 0;
Chunks.clear();
@@ -108,7 +119,7 @@ class DebugCounter {
LLVM_ABI static bool shouldExecuteImpl(CounterInfo &Counter);
inline static bool shouldExecute(CounterInfo &Counter) {
- if (!Counter.Active)
+ if (!Counter.getActive())
return true;
return shouldExecuteImpl(Counter);
}
@@ -116,7 +127,7 @@ class DebugCounter {
// Return true if a given counter had values set (either programatically or on
// the command line). This will return true even if those values are
// currently in a state where the counter will always execute.
- static bool isCounterSet(CounterInfo &Info) { return Info.IsSet; }
+ static bool isCounterSet(CounterInfo &Info) { return Info.getIsSet(); }
struct CounterState {
int64_t Count;
@@ -165,7 +176,7 @@ class DebugCounter {
void activateAllCounters() {
for (auto &[_, Counter] : Counters)
- Counter->Active = true;
+ Counter->setActive(true);
}
void resetAllCounters() {
diff --git a/llvm/include/llvm/Support/GenericDomTree.h b/llvm/include/llvm/Support/GenericDomTree.h
index 964e8412ce910..f9fb8263d368c 100644
--- a/llvm/include/llvm/Support/GenericDomTree.h
+++ b/llvm/include/llvm/Support/GenericDomTree.h
@@ -29,6 +29,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/CFGDiff.h"
#include "llvm/Support/CFGUpdate.h"
@@ -284,7 +285,8 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
protected:
// Dominators always have a single root, postdominators can have more.
- SmallVector<NodeT *, IsPostDom ? 4 : 1> Roots;
+ // Mutable only so const queries can update the DFS-valid flag.
+ mutable SmallVectorWithFlags<NodeT *, IsPostDom ? 4 : 1> Roots;
using DomTreeNodeStorageTy = SmallVector<DomTreeNodeBase<NodeT> *>;
DomTreeNodeStorageTy DomTreeNodes;
@@ -300,7 +302,8 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
/*GrowthDelay=*/2>
NodeAllocator;
- mutable bool DFSInfoValid = false;
+ bool isDFSInfoValid() const { return Roots.getFlag(0); }
+ void setDFSInfoValid(bool Value) const { Roots.setFlag(0, Value); }
mutable unsigned int SlowQueries = 0;
unsigned BlockNumberEpoch = 0;
@@ -483,12 +486,12 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
// Compare the result of the tree walk and the dfs numbers, if expensive
// checks are enabled.
#ifdef EXPENSIVE_CHECKS
- assert((!DFSInfoValid ||
+ assert((!isDFSInfoValid() ||
(dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
"Tree walk disagrees with dfs numbers!");
#endif
- if (DFSInfoValid)
+ if (isDFSInfoValid())
return B->DominatedBy(A);
// If we end up with too many slow queries, just update the
@@ -650,7 +653,7 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
assert(getNode(BB) == nullptr && "Block already in dominator tree!");
DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
assert(IDomNode && "Not immediate dominator specified for block!");
- DFSInfoValid = false;
+ setDFSInfoValid(false);
return createNode(BB, IDomNode);
}
@@ -663,7 +666,7 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
assert(getNode(BB) == nullptr && "Block already in dominator tree!");
assert(!this->isPostDominator() &&
"Cannot change root of post-dominator tree");
- DFSInfoValid = false;
+ setDFSInfoValid(false);
DomTreeNodeBase<NodeT> *NewNode = createNode(BB);
if (Roots.empty()) {
addRoot(BB);
@@ -685,7 +688,7 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
void changeImmediateDominator(DomTreeNodeBase<NodeT> *N,
DomTreeNodeBase<NodeT> *NewIDom) {
assert(N && NewIDom && "Cannot change null node pointers!");
- DFSInfoValid = false;
+ setDFSInfoValid(false);
N->setIDom(NewIDom);
}
@@ -702,7 +705,7 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
assert(Node && "Removing node that isn't in dominator tree.");
assert(Node->isLeaf() && "Node is not a leaf node.");
- DFSInfoValid = false;
+ setDFSInfoValid(false);
// Remove node from immediate dominator's children list.
if (DomTreeNodeBase<NodeT> *IDom = Node->getIDom())
@@ -737,7 +740,7 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
O << "Inorder PostDominator Tree: ";
else
O << "Inorder Dominator Tree: ";
- if (!DFSInfoValid)
+ if (!isDFSInfoValid())
O << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
O << "\n";
@@ -755,7 +758,7 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
/// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
/// dominator tree in dfs order.
void updateDFSNumbers() const {
- if (DFSInfoValid) {
+ if (isDFSInfoValid()) {
SlowQueries = 0;
return;
}
@@ -796,7 +799,7 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
}
SlowQueries = 0;
- DFSInfoValid = true;
+ setDFSInfoValid(true);
}
private:
@@ -845,7 +848,7 @@ template <typename NodeT, bool IsPostDom> class DominatorTreeBase {
Roots.clear();
RootNode = nullptr;
Parent = nullptr;
- DFSInfoValid = false;
+ setDFSInfoValid(false);
NodeAllocator.Reset();
SlowQueries = 0;
}
diff --git a/llvm/include/llvm/Support/GenericDomTreeConstruction.h b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
index 96fb16e5d4bb3..218d88c35a11f 100644
--- a/llvm/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
@@ -569,7 +569,9 @@ template <typename DomTreeT> struct SemiNCAInfo {
// Step #0: Number blocks in depth-first order and initialize variables used
// in later stages of the algorithm.
- DT.Roots = FindRoots(DT, PostViewBUI);
+ RootsT NewRoots = FindRoots(DT, PostViewBUI);
+ NewRoots.setFlags(DT.Roots.getFlags());
+ DT.Roots = std::move(NewRoots);
SNCA.doFullDFSWalk(DT, AlwaysDescend);
SNCA.runSemiNCA();
@@ -655,7 +657,7 @@ template <typename DomTreeT> struct SemiNCAInfo {
DT.Roots.push_back(From);
}
- DT.DFSInfoValid = false;
+ DT.setDFSInfoValid(false);
const TreeNodePtr ToTN = DT.getNode(To);
if (!ToTN)
@@ -685,8 +687,7 @@ template <typename DomTreeT> struct SemiNCAInfo {
return true;
}
- static bool isPermutation(const SmallVectorImpl<NodePtr> &A,
- const SmallVectorImpl<NodePtr> &B) {
+ static bool isPermutation(ArrayRef<NodePtr> A, ArrayRef<NodePtr> B) {
if (A.size() != B.size())
return false;
SmallPtrSet<NodePtr, 4> Set(llvm::from_range, A);
@@ -942,7 +943,7 @@ template <typename DomTreeT> struct SemiNCAInfo {
// If To dominates From -- nothing to do.
if (ToTN != NCD) {
- DT.DFSInfoValid = false;
+ DT.setDFSInfoValid(false);
const TreeNodePtr ToIDom = ToTN->getIDom();
LLVM_DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom "
@@ -1322,7 +1323,7 @@ template <typename DomTreeT> struct SemiNCAInfo {
// be valid, and when that is the case, we don't verify the numbers.
// Running time: O(N log(N)).
static bool VerifyDFSNumbers(const DomTreeT &DT) {
- if (!DT.DFSInfoValid || !DT.Parent)
+ if (!DT.isDFSInfoValid() || !DT.Parent)
return true;
const NodePtr RootBB = IsPostDom ? nullptr : *DT.root_begin();
diff --git a/llvm/include/llvm/Support/GlobPattern.h b/llvm/include/llvm/Support/GlobPattern.h
index 00a931db9f278..e887a5be4c0e9 100644
--- a/llvm/include/llvm/Support/GlobPattern.h
+++ b/llvm/include/llvm/Support/GlobPattern.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
@@ -95,7 +96,6 @@ class GlobPattern {
StringRef Pattern;
size_t PrefixSize = 0;
size_t SuffixSize = 0;
- bool SlashAgnostic = false;
struct SubGlobPattern {
/// \param Pat the pattern to match against
@@ -105,7 +105,7 @@ class GlobPattern {
LLVM_ABI bool match(StringRef S, bool SlashAgnostic) const;
StringRef getPat() const { return StringRef(Pat.data(), Pat.size()); }
/// \returns \p true if this sub-pattern matches exactly one string.
- bool isLiteral() const { return Brackets.empty() && !HasWildcard; }
+ bool isLiteral() const { return Brackets.empty() && !Pat.getFlag(0); }
// Brackets with their end position and matched bytes.
struct Bracket {
@@ -113,11 +113,11 @@ class GlobPattern {
BitVector Bytes;
};
SmallVector<Bracket, 0> Brackets;
- // Set while parsing if an unescaped '*' or '?' is present.
- bool HasWildcard = false;
- SmallVector<char, 0> Pat;
+ // Flag bit 0 is set if an unescaped '*' or '?' is present.
+ SmallVectorWithFlags<char, 0> Pat;
};
- SmallVector<SubGlobPattern, 1> SubGlobs;
+ // Flag bit 0 records slash-agnostic matching.
+ SmallVectorWithFlags<SubGlobPattern, 1> SubGlobs;
};
}
diff --git a/llvm/include/llvm/Support/LSP/Transport.h b/llvm/include/llvm/Support/LSP/Transport.h
index 4a831b8805acf..da43cd943582e 100644
--- a/llvm/include/llvm/Support/LSP/Transport.h
+++ b/llvm/include/llvm/Support/LSP/Transport.h
@@ -16,6 +16,7 @@
#define LLVM_SUPPORT_LSP_TRANSPORT_H
#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
@@ -88,13 +89,17 @@ class JSONTransport {
public:
JSONTransport(std::unique_ptr<JSONTransportInput> In, raw_ostream &Out,
bool PrettyOutput = false)
- : In(std::move(In)), Out(Out), PrettyOutput(PrettyOutput) {}
+ : In(std::move(In)), OutputBuffer(decltype(this->OutputBuffer)::withFlags(
+ unsigned(PrettyOutput))),
+ Out(Out) {}
JSONTransport(std::FILE *In, raw_ostream &Out,
JSONStreamStyle Style = JSONStreamStyle::Standard,
bool PrettyOutput = false)
- : In(std::make_unique<JSONTransportInputOverFile>(In, Style)), Out(Out),
- PrettyOutput(PrettyOutput) {}
+ : In(std::make_unique<JSONTransportInputOverFile>(In, Style)),
+ OutputBuffer(
+ decltype(this->OutputBuffer)::withFlags(unsigned(PrettyOutput))),
+ Out(Out) {}
/// The following methods are used to send a message to the LSP client.
LLVM_ABI void notify(StringRef Method, llvm::json::Value Params);
@@ -115,11 +120,12 @@ class JSONTransport {
private:
/// The input to read a message from.
std::unique_ptr<JSONTransportInput> In;
- SmallVector<char, 0> OutputBuffer;
+ llvm::SmallVectorWithFlags<char, 0> OutputBuffer;
/// The output file stream.
raw_ostream &Out;
/// If the output JSON should be formatted for easier readability.
- bool PrettyOutput;
+ bool getPrettyOutput() const { return OutputBuffer.getFlag(0); }
+ void setPrettyOutput(bool Value) { OutputBuffer.setFlag(0, Value); }
};
//===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/Support/SuffixTree.h b/llvm/include/llvm/Support/SuffixTree.h
index eac66d84d6f63..aafed0b51cb6d 100644
--- a/llvm/include/llvm/Support/SuffixTree.h
+++ b/llvm/include/llvm/Support/SuffixTree.h
@@ -33,6 +33,7 @@
#define LLVM_SUPPORT_SUFFIXTREE_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SuffixTreeNode.h"
@@ -166,7 +167,7 @@ class SuffixTree {
RepeatedSubstring RS;
/// The nodes left to visit.
- SmallVector<SuffixTreeInternalNode *> InternalNodesToVisit;
+ llvm::SmallVectorWithFlags<SuffixTreeInternalNode *> InternalNodesToVisit;
/// The minimum length of a repeated substring to find.
/// Since we're outlining, we want at least two instructions in the range.
@@ -178,7 +179,12 @@ class SuffixTree {
const std::vector<SuffixTreeLeafNode *> &LeafNodes;
/// Whether to consider leaf descendants or only leaf children.
- bool OutlinerLeafDescendants = !LeafNodes.empty();
+ bool getOutlinerLeafDescendants() const {
+ return InternalNodesToVisit.getFlag(0);
+ }
+ void setOutlinerLeafDescendants(bool Value) {
+ InternalNodesToVisit.setFlag(0, Value);
+ }
/// Move the iterator to the next repeated substring.
LLVM_ABI void advance();
@@ -208,7 +214,10 @@ class SuffixTree {
RepeatedSubstringIterator(
SuffixTreeInternalNode *N,
const std::vector<SuffixTreeLeafNode *> &LeafNodes = {})
- : N(N), LeafNodes(LeafNodes) {
+ : N(N),
+ InternalNodesToVisit(decltype(this->InternalNodesToVisit)::withFlags(
+ unsigned(bool(!LeafNodes.empty())))),
+ LeafNodes(LeafNodes) {
// Do we have a non-null node?
if (!N)
return;
diff --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h
index 7ba43176c6e79..7f08ddc84fe4a 100644
--- a/llvm/include/llvm/Support/YAMLTraits.h
+++ b/llvm/include/llvm/Support/YAMLTraits.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -1896,6 +1897,18 @@ struct SequenceTraits<
SmallVectorImpl<T>,
std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
: SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
+template <typename T, unsigned N, unsigned FlagBits>
+struct SequenceTraits<
+ SmallVectorWithFlags<T, N, FlagBits>,
+ std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
+ : SequenceTraitsImpl<SmallVectorWithFlags<T, N, FlagBits>,
+ SequenceElementTraits<T>::flow> {};
+template <typename T, unsigned FlagBits>
+struct SequenceTraits<
+ SmallVectorWithFlagsImpl<T, FlagBits>,
+ std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
+ : SequenceTraitsImpl<SmallVectorWithFlagsImpl<T, FlagBits>,
+ SequenceElementTraits<T>::flow> {};
template <typename T>
struct SequenceTraits<
MutableArrayRef<T>,
diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h
index 67bc27f6a2d1f..94e84a7d592bf 100644
--- a/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -105,6 +105,7 @@
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
#include "llvm/Analysis/CFG.h"
@@ -1223,7 +1224,7 @@ struct InformationCache {
}
/// Return the instructions in \p F that may read or write memory.
- InstructionVectorTy &getReadOrWriteInstsForFunction(const Function &F) {
+ auto &getReadOrWriteInstsForFunction(const Function &F) {
return getFunctionInfo(F).RWInsts;
}
@@ -1240,14 +1241,14 @@ struct InformationCache {
/// Return true if \p F has the "kernel" function attribute
bool isKernel(const Function &F) {
FunctionInfo &FI = getFunctionInfo(F);
- return FI.IsKernel;
+ return FI.getIsKernel();
}
/// Return true if \p Arg is involved in a must-tail call, thus the argument
/// of the caller or callee.
bool isInvolvedInMustTailCall(const Argument &Arg) {
FunctionInfo &FI = getFunctionInfo(*Arg.getParent());
- return FI.CalledViaMustTail || FI.ContainsMustTailCall;
+ return FI.getCalledViaMustTail() || FI.getContainsMustTailCall();
}
bool isOnlyUsedByAssume(const Instruction &I) const {
@@ -1312,16 +1313,22 @@ struct InformationCache {
/// A map from functions to their instructions that may read or write
/// memory.
- InstructionVectorTy RWInsts;
+ llvm::SmallVectorWithFlagsFor<InstructionVectorTy, 3> RWInsts;
/// Function is called by a `musttail` call.
- bool CalledViaMustTail;
+ bool getCalledViaMustTail() const { return RWInsts.getFlag(0); }
+ bool setCalledViaMustTail(bool Value) {
+ RWInsts.setFlag(0, Value);
+ return Value;
+ }
/// Function contains a `musttail` call.
- bool ContainsMustTailCall;
+ bool getContainsMustTailCall() const { return RWInsts.getFlag(1); }
+ void setContainsMustTailCall(bool Value) { RWInsts.setFlag(1, Value); }
/// Function has the `"kernel"` attribute
- bool IsKernel;
+ bool getIsKernel() const { return RWInsts.getFlag(2); }
+ void setIsKernel(bool Value) { RWInsts.setFlag(2, Value); }
};
/// A map type from functions to informatio about it.
diff --git a/llvm/include/llvm/Transforms/IPO/Instrumentor.h b/llvm/include/llvm/Transforms/IPO/Instrumentor.h
index e7e6c52d8c816..d78b4dba9a9b0 100644
--- a/llvm/include/llvm/Transforms/IPO/Instrumentor.h
+++ b/llvm/include/llvm/Transforms/IPO/Instrumentor.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
@@ -501,13 +502,17 @@ struct InstrumentationOpportunity {
/// The list of possible arguments for the instrumentation runtime function.
/// The order within the array determines the order of arguments. Arguments
/// may be disabled and will not be passed to the function call.
- SmallVector<IRTArg> IRTArgs;
+ llvm::SmallVectorWithFlags<IRTArg> IRTArgs;
/// Flag names and their integer bitmask values.
StringMap<int32_t> FlagNames;
/// Whether the opportunity is enabled.
- bool Enabled = true;
+ bool getEnabled() const { return !IRTArgs.getFlag(0); }
+ bool setEnabled(bool Value) {
+ IRTArgs.setFlag(0, !Value);
+ return Value;
+ }
/// A filter expression to be matched against runtime property values. If the
/// filter is non-empty, only instrumentations matching the filter will be
diff --git a/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h b/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
index 7a872ef1021b2..2ce9745c28b92 100644
--- a/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
+++ b/llvm/include/llvm/Transforms/Scalar/ConstantHoisting.h
@@ -42,6 +42,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/PassManager.h"
#include <algorithm>
@@ -152,7 +153,8 @@ class ConstantHoistingPass
const DataLayout *DL;
BasicBlock *Entry;
ProfileSummaryInfo *PSI;
- bool OptForSize;
+ bool getOptForSize() const { return ConstIntInfoVec.getFlag(0); }
+ void setOptForSize(bool Value) { ConstIntInfoVec.setFlag(0, Value); }
/// Keeps track of constant candidates found in the function.
using ConstCandVecType = std::vector<consthoist::ConstantCandidate>;
@@ -163,7 +165,7 @@ class ConstantHoistingPass
/// These are the final constants we decided to hoist.
using ConstInfoVecType = SmallVector<consthoist::ConstantInfo, 8>;
using GVInfoVecMapType = MapVector<GlobalVariable *, ConstInfoVecType>;
- ConstInfoVecType ConstIntInfoVec;
+ llvm::SmallVectorWithFlagsFor<ConstInfoVecType, 1> ConstIntInfoVec;
GVInfoVecMapType ConstGEPInfoMap;
/// Keep track of cast instructions we already cloned.
diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h
index 119084eea7238..268dca0fdcbbc 100644
--- a/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/InlineCost.h"
@@ -264,7 +265,10 @@ class InlineFunctionInfo {
BlockFrequencyInfo *CallerBFI = nullptr,
BlockFrequencyInfo *CalleeBFI = nullptr, bool UpdateProfile = true)
: GetAssumptionCache(GetAssumptionCache), PSI(PSI), CallerBFI(CallerBFI),
- CalleeBFI(CalleeBFI), UpdateProfile(UpdateProfile) {}
+ CalleeBFI(CalleeBFI),
+ StaticAllocas(
+ decltype(this->StaticAllocas)::withFlags(unsigned(UpdateProfile))) {
+ }
/// If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
@@ -274,7 +278,7 @@ class InlineFunctionInfo {
/// InlineFunction fills this in with all static allocas that get copied into
/// the caller.
- SmallVector<AllocaInst *, 4> StaticAllocas;
+ llvm::SmallVectorWithFlags<AllocaInst *, 4> StaticAllocas;
/// All of the new call sites inlined into the caller.
///
@@ -286,7 +290,8 @@ class InlineFunctionInfo {
/// Update profile for callee as well as cloned version. We need to do this
/// for regular inlining, but not for inlining from sample profile loader.
- bool UpdateProfile;
+ bool getUpdateProfile() const { return StaticAllocas.getFlag(0); }
+ void setUpdateProfile(bool Value) { StaticAllocas.setFlag(0, Value); }
void reset() {
StaticAllocas.clear();
diff --git a/llvm/include/llvm/Transforms/Utils/CodeExtractor.h b/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
index 6285bbf29612d..6e4b390fdcba8 100644
--- a/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
+++ b/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/IRBuilder.h"
@@ -92,7 +93,7 @@ class LLVM_ABI CodeExtractor {
// Various bits of state computed on construction.
DominatorTree *const DT;
- const bool AggregateArgs;
+ bool getAggregateArgs() const { return ExtractedFuncRetVals.getFlag(0); }
BlockFrequencyInfo *BFI;
BranchProbabilityInfo *BPI;
AssumptionCache *AC;
@@ -111,7 +112,8 @@ class LLVM_ABI CodeExtractor {
SmallVector<BasicBlock *> DeallocationBlocks;
/// If true, varargs functions can be extracted.
- bool AllowVarArgs;
+ bool getAllowVarArgs() const { return ExtractedFuncRetVals.getFlag(1); }
+ void setAllowVarArgs(bool Value) { ExtractedFuncRetVals.setFlag(1, Value); }
/// Bits of intermediate state computed at various phases of extraction.
SetVector<BasicBlock *> Blocks;
@@ -132,7 +134,10 @@ class LLVM_ABI CodeExtractor {
/// When there are 3 or more exit blocks, leaving the extracted function via
/// the first block it returns 0. When leaving via the second entry it returns
/// 1, etc.
- SmallVector<BasicBlock *> ExtractedFuncRetVals;
+ llvm::SmallVectorWithFlags<
+ BasicBlock *,
+ llvm::CalculateSmallVectorDefaultInlinedElements<BasicBlock *>::value, 4>
+ ExtractedFuncRetVals;
/// Suffix to use when creating extracted function (appended to the original
/// function name + "."). If empty, the default is to use the entry block
@@ -141,11 +146,21 @@ class LLVM_ABI CodeExtractor {
/// If true, the outlined function has aggregate argument in zero address
/// space.
- bool ArgsInZeroAddressSpace;
+ bool getArgsInZeroAddressSpace() const {
+ return ExtractedFuncRetVals.getFlag(2);
+ }
+ void setArgsInZeroAddressSpace(bool Value) {
+ ExtractedFuncRetVals.setFlag(2, Value);
+ }
// If true, the outlined function always return void even when there is only
// one output.
- bool VoidReturnWithSingleOutput;
+ bool getVoidReturnWithSingleOutput() const {
+ return ExtractedFuncRetVals.getFlag(3);
+ }
+ void setVoidReturnWithSingleOutput(bool Value) {
+ ExtractedFuncRetVals.setFlag(3, Value);
+ }
// If set, the return value of the outline function.
Value *FuncRetVal = nullptr;
diff --git a/llvm/include/llvm/Transforms/Utils/LockstepReverseIterator.h b/llvm/include/llvm/Transforms/Utils/LockstepReverseIterator.h
index 5b92b33a10ea0..e642a075a8d2e 100644
--- a/llvm/include/llvm/Transforms/Utils/LockstepReverseIterator.h
+++ b/llvm/include/llvm/Transforms/Utils/LockstepReverseIterator.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instruction.h"
@@ -45,8 +46,8 @@ class LockstepReverseIterator
using Base = std::conditional_t<EarlyFailure, NoActiveBlocksOption,
ActiveBlocksOption>;
ArrayRef<BasicBlock *> Blocks;
- SmallVector<Instruction *, 4> Insts;
- bool Fail;
+ SmallVectorWithFlags<Instruction *, 4> Insts;
+ bool failed() const { return Insts.getFlag(0); }
public:
LockstepReverseIterator(ArrayRef<BasicBlock *> Blocks) : Blocks(Blocks) {
@@ -54,7 +55,7 @@ class LockstepReverseIterator
}
void reset() {
- Fail = false;
+ Insts.setFlag(0, false);
if constexpr (!EarlyFailure) {
this->ActiveBlocks.clear();
this->ActiveBlocks.insert_range(Blocks);
@@ -65,7 +66,7 @@ class LockstepReverseIterator
if (!Prev) {
// Block wasn't big enough - only contained a terminator.
if constexpr (EarlyFailure) {
- Fail = true;
+ Insts.setFlag(0, true);
return;
} else {
this->ActiveBlocks.remove(BB);
@@ -75,10 +76,10 @@ class LockstepReverseIterator
Insts.push_back(Prev);
}
if (Insts.empty())
- Fail = true;
+ Insts.setFlag(0, true);
}
- bool isValid() const { return !Fail; }
+ bool isValid() const { return !failed(); }
ArrayRef<Instruction *> operator*() const { return Insts; }
// Note: This needs to return a SmallSetVector as the elements of
@@ -104,7 +105,7 @@ class LockstepReverseIterator
}
LockstepReverseIterator &operator--() {
- if (Fail)
+ if (failed())
return *this;
SmallVector<Instruction *, 4> NewInsts;
for (Instruction *Inst : Insts) {
@@ -113,7 +114,7 @@ class LockstepReverseIterator
if constexpr (!EarlyFailure) {
this->ActiveBlocks.remove(Inst->getParent());
} else {
- Fail = true;
+ Insts.setFlag(0, true);
return *this;
}
} else {
@@ -121,30 +122,30 @@ class LockstepReverseIterator
}
}
if (NewInsts.empty())
- Fail = true;
+ Insts.setFlag(0, true);
else
- Insts = NewInsts;
+ Insts.assign(NewInsts.begin(), NewInsts.end());
return *this;
}
LockstepReverseIterator &operator++() {
static_assert(EarlyFailure, "Unknown method");
- if (Fail)
+ if (failed())
return *this;
SmallVector<Instruction *, 4> NewInsts;
for (Instruction *Inst : Insts) {
Instruction *Next = Inst->getNextNode();
// Already at end of block.
if (!Next) {
- Fail = true;
+ Insts.setFlag(0, true);
return *this;
}
NewInsts.push_back(Next);
}
if (NewInsts.empty())
- Fail = true;
+ Insts.setFlag(0, true);
else
- Insts = NewInsts;
+ Insts.assign(NewInsts.begin(), NewInsts.end());
return *this;
}
};
diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/llvm/include/llvm/Transforms/Utils/LoopUtils.h
index a68b928985316..740200874b56d 100644
--- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h
@@ -13,6 +13,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
#define LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
@@ -673,14 +674,18 @@ LLVM_ABI Value *addDiffRuntimeChecks(Instruction *Loc,
struct IVConditionInfo {
/// Instructions that need to be duplicated and checked for the unswitching
/// condition.
- SmallVector<Instruction *> InstToDuplicate;
+ llvm::SmallVectorWithFlags<Instruction *> InstToDuplicate;
/// Constant to indicate for which value the condition is invariant.
Constant *KnownValue = nullptr;
/// True if the partially invariant path is no-op (=does not have any
/// side-effects and no loop value is used outside the loop).
- bool PathIsNoop = true;
+ bool getPathIsNoop() const { return !InstToDuplicate.getFlag(0); }
+ bool setPathIsNoop(bool Value) {
+ InstToDuplicate.setFlag(0, !Value);
+ return Value;
+ }
/// If the partially invariant path reaches a single exit block, ExitForPath
/// is set to that block. Otherwise it is nullptr.
diff --git a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
index 5590109adcbc5..e0085dc86db20 100644
--- a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
+++ b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/StackSafetyAnalysis.h"
@@ -51,7 +52,7 @@ struct AllocaInfo {
LLVM_ABI void
forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT,
const LoopInfo &LI, const AllocaInfo &AInfo,
- const SmallVectorImpl<Instruction *> &RetVec,
+ ArrayRef<Instruction *> RetVec,
llvm::function_ref<void(Instruction *)> Callback);
LLVM_ABI bool isSupportedLifetime(const AllocaInfo &AInfo,
@@ -61,8 +62,9 @@ LLVM_ABI Instruction *getUntagLocationIfFunctionExit(Instruction &Inst);
struct StackInfo {
MapVector<AllocaInst *, AllocaInfo> AllocasToInstrument;
- SmallVector<Instruction *, 8> RetVec;
- bool CallsReturnTwice = false;
+ llvm::SmallVectorWithFlags<Instruction *, 8> RetVec;
+ bool getCallsReturnTwice() const { return RetVec.getFlag(0); }
+ void setCallsReturnTwice(bool Value) { RetVec.setFlag(0, Value); }
};
enum class AllocaInterestingness {
diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
index 8a4ca594b77bb..7865a3e0b6438 100644
--- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
+++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/InstSimplifyFolder.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
@@ -72,7 +73,8 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
const char *IVName;
/// Indicates whether LCSSA phis should be created for inserted values.
- bool PreserveLCSSA;
+ bool getPreserveLCSSA() const { return InsertPointGuards.getFlag(0); }
+ void setPreserveLCSSA(bool Value) { InsertPointGuards.setFlag(0, Value); }
// InsertedExpressions caches Values for reuse, so must track RAUW.
DenseMap<std::pair<SCEVUse, Instruction *>, TrackingVH<Value>>
@@ -129,17 +131,20 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
/// 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;
+ bool getCanonicalMode() const { return InsertPointGuards.getFlag(1); }
+ void setCanonicalMode(bool Value) { InsertPointGuards.setFlag(1, Value); }
/// 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;
+ bool getLSRMode() const { return InsertPointGuards.getFlag(2); }
+ void setLSRMode(bool Value) { InsertPointGuards.setFlag(2, Value); }
/// When true, rewrite any divisors of UDiv expressions that may be 0 to
/// umax(Divisor, 1) to avoid introducing UB. If the divisor may be poison,
/// freeze it first.
- bool SafeUDivMode = false;
+ bool getSafeUDivMode() const { return InsertPointGuards.getFlag(3); }
+ void setSafeUDivMode(bool Value) { InsertPointGuards.setFlag(3, Value); }
typedef IRBuilder<InstSimplifyFolder, IRBuilderCallbackInserter> BuilderType;
BuilderType Builder;
@@ -181,7 +186,7 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
/// Stack of pointers to saved insert points, used to keep insert points
/// consistent when instructions are moved.
- SmallVector<SCEVInsertPointGuard *, 8> InsertPointGuards;
+ llvm::SmallVectorWithFlags<SCEVInsertPointGuard *, 8, 4> InsertPointGuards;
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
const char *DebugType;
@@ -193,12 +198,13 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
/// Construct a SCEVExpander in "canonical" mode.
explicit SCEVExpander(ScalarEvolution &SE, const char *Name,
bool PreserveLCSSA = true)
- : SE(SE), DL(SE.getDataLayout()), IVName(Name),
- PreserveLCSSA(PreserveLCSSA), IVIncInsertLoop(nullptr),
- IVIncInsertPos(nullptr), CanonicalMode(true), LSRMode(false),
+ : SE(SE), DL(SE.getDataLayout()), IVName(Name), IVIncInsertLoop(nullptr),
+ IVIncInsertPos(nullptr),
Builder(SE.getModule(), InstSimplifyFolder(DL),
IRBuilderCallbackInserter(
- [this](Instruction *I) { rememberInstruction(I); })) {
+ [this](Instruction *I) { rememberInstruction(I); })),
+ InsertPointGuards(decltype(this->InsertPointGuards)::withFlags(
+ unsigned(PreserveLCSSA) | 2)) {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
DebugType = "";
#endif
@@ -380,7 +386,7 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
/// Set the current IV increment loop and position.
void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
- assert(!CanonicalMode &&
+ assert(!getCanonicalMode() &&
"IV increment positions are not supported in CanonicalMode");
IVIncInsertLoop = L;
IVIncInsertPos = Pos;
@@ -389,7 +395,7 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
/// 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 &&
+ assert(!getCanonicalMode() &&
"Post-inc expansion is not supported in CanonicalMode");
PostIncLoops = L;
}
@@ -406,9 +412,9 @@ class SCEVExpander : public SCEVUseVisitor<SCEVExpander, Value *> {
/// 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 disableCanonicalMode() { setCanonicalMode(false); }
- void enableLSRMode() { LSRMode = true; }
+ void enableLSRMode() { setLSRMode(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
diff --git a/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h b/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
index c6f8c61fcb3cb..83230519bd525 100644
--- a/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
+++ b/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
@@ -27,6 +27,7 @@
#define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZATIONLEGALITY_H
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/Support/TypeSize.h"
@@ -287,8 +288,10 @@ class LoopVectorizationLegality {
AssumptionCache *AC, bool AllowRuntimeSCEVChecks,
AAResults *AA)
: Opts(Opts), TheLoop(L), LI(LI), PSE(PSE), TTI(TTI), TLI(TLI), DT(DT),
- LAIs(LAIs), ORE(ORE), Requirements(R), Hints(H), DB(DB), AC(AC),
- AllowRuntimeSCEVChecks(AllowRuntimeSCEVChecks), AA(AA) {}
+ LAIs(LAIs), ORE(ORE), Requirements(R), Hints(H), DB(DB), AC(AC), AA(AA),
+ CountableExitingBlocks(
+ decltype(this->CountableExitingBlocks)::withFlags(
+ unsigned(AllowRuntimeSCEVChecks))) {}
/// ReductionList contains the reduction descriptors for all
/// of the reductions that were found in the loop.
@@ -462,7 +465,7 @@ class LoopVectorizationLegality {
/// Returns true if there is at least one function call in the loop which
/// has a vectorized variant available.
- bool hasVectorCallVariants() const { return VecCallVariantsFound; }
+ bool hasVectorCallVariants() const { return getVecCallVariantsFound(); }
/// Returns a HistogramInfo* for the given instruction if it was determined
/// to be part of a load -> update -> store sequence where multiple lanes
@@ -494,7 +497,7 @@ class LoopVectorizationLegality {
/// Returns all exiting blocks with a countable exit, i.e. the
/// exit-not-taken count is known exactly at compile time.
- const SmallVector<BasicBlock *, 4> &getCountableExitingBlocks() const {
+ ArrayRef<BasicBlock *> getCountableExitingBlocks() const {
return CountableExitingBlocks;
}
@@ -726,7 +729,12 @@ class LoopVectorizationLegality {
SmallVector<HistogramInfo, 1> Histograms;
/// Whether or not creating SCEV predicates is allowed.
- bool AllowRuntimeSCEVChecks;
+ bool getAllowRuntimeSCEVChecks() const {
+ return CountableExitingBlocks.getFlag(0);
+ }
+ void setAllowRuntimeSCEVChecks(bool Value) {
+ CountableExitingBlocks.setFlag(0, Value);
+ }
// Alias Analysis results used to check for possible aliasing with loads
// used in uncountable exit conditions.
@@ -736,11 +744,17 @@ class LoopVectorizationLegality {
/// vectorized variant, record that fact so that LoopVectorize can
/// (potentially) make a better decision on the maximum VF and enable
/// the use of those function variants.
- bool VecCallVariantsFound = false;
+ bool getVecCallVariantsFound() const {
+ return CountableExitingBlocks.getFlag(1);
+ }
+ bool setVecCallVariantsFound(bool Value) {
+ CountableExitingBlocks.setFlag(1, Value);
+ return Value;
+ }
/// Keep track of all the countable and uncountable exiting blocks if
/// the exact backedge taken count is not computable.
- SmallVector<BasicBlock *, 4> CountableExitingBlocks;
+ llvm::SmallVectorWithFlags<BasicBlock *, 4, 2> CountableExitingBlocks;
/// Records whether we have an uncountable early exit in a loop that's
/// either read-only or read-write.
diff --git a/llvm/lib/Analysis/AssumptionCache.cpp b/llvm/lib/Analysis/AssumptionCache.cpp
index 762109f1a7b38..d3b1ca214779c 100644
--- a/llvm/lib/Analysis/AssumptionCache.cpp
+++ b/llvm/lib/Analysis/AssumptionCache.cpp
@@ -204,7 +204,7 @@ void AssumptionCache::AffectedValueCallbackVH::allUsesReplacedWith(Value *NV) {
}
void AssumptionCache::scanFunction() {
- assert(!Scanned && "Tried to scan the function twice!");
+ assert(!isScanned() && "Tried to scan the function twice!");
assert(AssumeHandles.empty() && "Already have assumes when scanning!");
// Go through all instructions in all blocks, add all calls to @llvm.assume
@@ -215,7 +215,7 @@ void AssumptionCache::scanFunction() {
AssumeHandles.push_back(&I);
// Mark the scan as complete.
- Scanned = true;
+ AssumeHandles.setFlag(0, true);
// Update affected values.
for (auto &A : AssumeHandles)
@@ -246,7 +246,7 @@ findCacheViolation(const Function &F, ArrayRef<WeakVH> Assumptions,
void AssumptionCache::registerAssumption(AssumeInst *CI) {
// If we haven't scanned the function yet, just drop this assumption. It will
// be found when we scan later.
- if (!Scanned)
+ if (!isScanned())
return;
AssumeHandles.push_back(CI);
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 7a79b0d6e24f1..967eedb346bd0 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1437,7 +1437,7 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
// on corresponding edges. Don't do this if we are analyzing across
// iterations, as we may pick a different phi entry in different iterations.
if (const PHINode *PN2 = dyn_cast<PHINode>(V2))
- if (PN2->getParent() == PN->getParent() && !AAQI.MayBeCrossIteration) {
+ if (PN2->getParent() == PN->getParent() && !AAQI.mayBeCrossIteration()) {
std::optional<AliasResult> Alias;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
AliasResult ThisAlias = AAQI.AAR.alias(
@@ -1515,7 +1515,10 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
// In the recursive alias queries below, we may compare values from two
// different loop iterations.
- SaveAndRestore SavedMayBeCrossIteration(AAQI.MayBeCrossIteration, true);
+ bool WasCrossIteration = AAQI.mayBeCrossIteration();
+ auto RestoreCrossIteration =
+ scope_exit([&] { AAQI.setMayBeCrossIteration(WasCrossIteration); });
+ AAQI.setMayBeCrossIteration(true);
AliasResult Alias = AAQI.AAR.alias(MemoryLocation(V1Srcs[0], PNSize),
MemoryLocation(V2, V2Size), AAQI);
@@ -1701,8 +1704,8 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
// otherwise infinitely recursive queries. Include MayBeCrossIteration in the
// cache key, because some cases where MayBeCrossIteration==false returns
// MustAlias or NoAlias may become MayAlias under MayBeCrossIteration==true.
- AAQueryInfo::LocPair Locs({V1, V1Size, AAQI.MayBeCrossIteration},
- {V2, V2Size, AAQI.MayBeCrossIteration});
+ AAQueryInfo::LocPair Locs({V1, V1Size, AAQI.mayBeCrossIteration()},
+ {V2, V2Size, AAQI.mayBeCrossIteration()});
const bool Swapped = V1 > V2;
if (Swapped)
std::swap(Locs.first, Locs.second);
@@ -1874,7 +1877,7 @@ bool BasicAAResult::isValueEqualInPotentialCycles(const Value *V,
if (V != V2)
return false;
- if (!AAQI.MayBeCrossIteration)
+ if (!AAQI.mayBeCrossIteration())
return true;
// Non-instructions and instructions in the entry block cannot be part of
@@ -2048,7 +2051,7 @@ std::optional<APInt> BasicAAResult::computeMinAbsVarOffset(
const VariableGEPIndex &Var1 = VarIndices[1];
bool Preconditions =
Var0.Val.TruncBits == 0 && Var0.Val.hasSameCastsAs(Var1.Val) &&
- !AAQI.MayBeCrossIteration && MultiplyByScaleNoWrap(Var0) &&
+ !AAQI.mayBeCrossIteration() && MultiplyByScaleNoWrap(Var0) &&
MultiplyByScaleNoWrap(Var1);
if (!Preconditions)
diff --git a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
index 66c36f36d7d92..062ae493b7ca8 100644
--- a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
+++ b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp
@@ -149,8 +149,8 @@ void Distribution::add(const BlockNode &Node, uint64_t Amount,
// Check for overflow. It should be impossible to overflow twice.
bool IsOverflow = NewTotal < Total;
- assert(!(DidOverflow && IsOverflow) && "unexpected repeated overflow");
- DidOverflow |= IsOverflow;
+ assert(!(Weights.getFlag(0) && IsOverflow) && "unexpected repeated overflow");
+ Weights.setFlag(0, Weights.getFlag(0) || IsOverflow);
// Update the total.
Total = NewTotal;
@@ -251,7 +251,7 @@ void Distribution::normalize() {
// If we shift at all, shift by 1 extra. Otherwise, the lower limit of 1
// for each weight can cause a 32-bit overflow.
int Shift = 0;
- if (DidOverflow)
+ if (Weights.getFlag(0))
Shift = 33;
else if (Total > UINT32_MAX)
Shift = 33 - llvm::countl_zero(Total);
@@ -405,7 +405,7 @@ void BlockFrequencyInfoImplBase::packageLoop(LoopData &Loop) {
Loop->Exits.clear();
LLVM_DEBUG(dbgs() << " - node: " << getBlockName(M.Index) << "\n");
}
- Loop.IsPackaged = true;
+ Loop.setIsPackaged(true);
}
#ifndef NDEBUG
@@ -501,7 +501,7 @@ static void unwrapLoop(BlockFrequencyInfoImplBase &BFI, LoopData &Loop) {
<< ": mass = " << Loop.Mass << ", scale = " << Loop.Scale
<< "\n");
Loop.Scale *= Loop.Mass.toScaled();
- Loop.IsPackaged = false;
+ Loop.setIsPackaged(false);
LLVM_DEBUG(dbgs() << " => combined-scale = " << Loop.Scale << "\n");
// Propagate the head scale through the loop. Since members are visited in
diff --git a/llvm/lib/Analysis/ImportedFunctionsInliningStatistics.cpp b/llvm/lib/Analysis/ImportedFunctionsInliningStatistics.cpp
index f550cd6e1c68e..21f6331879a9f 100644
--- a/llvm/lib/Analysis/ImportedFunctionsInliningStatistics.cpp
+++ b/llvm/lib/Analysis/ImportedFunctionsInliningStatistics.cpp
@@ -39,7 +39,10 @@ ImportedFunctionsInliningStatistics::createInlineGraphNode(const Function &F) {
auto &ValueLookup = NodesMap[F.getName()];
if (!ValueLookup) {
ValueLookup = std::make_unique<InlineGraphNode>();
- ValueLookup->Imported = F.hasMetadata("thinlto_src_module");
+ [&] {
+ auto PackedFlagValue = F.hasMetadata("thinlto_src_module");
+ return ValueLookup->setImported(PackedFlagValue);
+ }();
}
return *ValueLookup;
}
@@ -51,7 +54,7 @@ void ImportedFunctionsInliningStatistics::recordInline(const Function &Caller,
InlineGraphNode &CalleeNode = createInlineGraphNode(Callee);
CalleeNode.NumberOfInlines++;
- if (!CallerNode.Imported && !CalleeNode.Imported) {
+ if (!CallerNode.getImported() && !CalleeNode.getImported()) {
// 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
@@ -61,7 +64,7 @@ void ImportedFunctionsInliningStatistics::recordInline(const Function &Caller,
}
CallerNode.InlinedCallees.push_back(&CalleeNode);
- if (!CallerNode.Imported) {
+ if (!CallerNode.getImported()) {
// 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.");
@@ -121,7 +124,7 @@ void ImportedFunctionsInliningStatistics::dump(const bool Verbose) {
if (Node->second->NumberOfInlines == 0)
continue;
- if (Node->second->Imported) {
+ if (Node->second->getImported()) {
InlinedImportedFunctionsCount++;
InlinedImportedFunctionsToImportingModuleCount +=
int(Node->second->NumberOfRealInlines > 0);
@@ -133,7 +136,7 @@ void ImportedFunctionsInliningStatistics::dump(const bool Verbose) {
if (Verbose)
Ostream << "Inlined "
- << (Node->second->Imported ? "imported " : "not imported ")
+ << (Node->second->getImported() ? "imported " : "not imported ")
<< "function [" << Node->first() << "]"
<< ": #inlines = " << Node->second->NumberOfInlines
<< ", #inlines_to_importing_module = "
@@ -178,17 +181,17 @@ void ImportedFunctionsInliningStatistics::calculateRealInlines() {
for (const auto &Name : NonImportedCallers) {
auto &Node = *NodesMap[Name];
- if (!Node.Visited)
+ if (!Node.getVisited())
dfs(Node);
}
}
void ImportedFunctionsInliningStatistics::dfs(InlineGraphNode &GraphNode) {
- assert(!GraphNode.Visited);
- GraphNode.Visited = true;
+ assert(!GraphNode.getVisited());
+ GraphNode.setVisited(true);
for (auto *const InlinedFunctionNode : GraphNode.InlinedCallees) {
InlinedFunctionNode->NumberOfRealInlines++;
- if (!InlinedFunctionNode->Visited)
+ if (!InlinedFunctionNode->getVisited())
dfs(*InlinedFunctionNode);
}
}
diff --git a/llvm/lib/Analysis/KernelInfo.cpp b/llvm/lib/Analysis/KernelInfo.cpp
index 4594c06859100..21c195ce9463b 100644
--- a/llvm/lib/Analysis/KernelInfo.cpp
+++ b/llvm/lib/Analysis/KernelInfo.cpp
@@ -13,6 +13,7 @@
#include "llvm/Analysis/KernelInfo.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/TargetTransformInfo.h"
@@ -38,10 +39,11 @@ class KernelInfo {
TargetMachine *TM);
/// Whether the function has external linkage and is not a kernel function.
- bool ExternalNotKernel = false;
+ bool getExternalNotKernel() const { return LaunchBounds.getFlag(0); }
+ void setExternalNotKernel(bool Value) { LaunchBounds.setFlag(0, Value); }
/// Launch bounds.
- SmallVector<std::pair<StringRef, int64_t>> LaunchBounds;
+ llvm::SmallVectorWithFlags<std::pair<StringRef, int64_t>> LaunchBounds;
/// The number of alloca instructions inside the function, the number of those
/// with allocation sizes that cannot be determined at compile time, and the
@@ -289,12 +291,15 @@ void KernelInfo::emitKernelInfo(Function &F, FunctionAnalysisManager &FAM,
KI.FlatAddrspace = TheTTI.getFlatAddressSpace();
// Record function properties.
- KI.ExternalNotKernel = F.hasExternalLinkage() && !F.hasKernelCallingConv();
+ KI.setExternalNotKernel(F.hasExternalLinkage() && !F.hasKernelCallingConv());
for (StringRef Name : {"omp_target_num_teams", "omp_target_thread_limit"}) {
if (auto Val = parseFnAttrAsInteger(F, Name))
KI.LaunchBounds.push_back({Name, *Val});
}
- TheTTI.collectKernelLaunchBounds(F, KI.LaunchBounds);
+ SmallVector<std::pair<StringRef, int64_t>> LaunchBounds;
+ LaunchBounds = std::move(KI.LaunchBounds);
+ TheTTI.collectKernelLaunchBounds(F, LaunchBounds);
+ KI.LaunchBounds.assign(std::move(LaunchBounds));
auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
for (const auto &BB : F)
@@ -302,7 +307,7 @@ void KernelInfo::emitKernelInfo(Function &F, FunctionAnalysisManager &FAM,
#define REMARK_PROPERTY(PROP_NAME) \
remarkProperty(ORE, F, #PROP_NAME, KI.PROP_NAME)
- REMARK_PROPERTY(ExternalNotKernel);
+ REMARK_PROPERTY(getExternalNotKernel());
for (auto LB : KI.LaunchBounds)
remarkProperty(ORE, F, LB.first, LB.second);
REMARK_PROPERTY(Allocas);
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index e0543aa71a77e..c28c2495b7889 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
@@ -667,7 +668,8 @@ SmallVector<RuntimePointerCheck, 4> RuntimePointerChecking::generateChecks() {
const RuntimeCheckingPtrGroup &CGJ = CheckingGroups[J];
if (needsChecking(CGI, CGJ)) {
- CanUseDiffCheck = CanUseDiffCheck && tryToCreateDiffCheck(CGI, CGJ);
+ DiffChecks.setFlag(1, DiffChecks.getFlag(1) ||
+ !tryToCreateDiffCheck(CGI, CGJ));
Checks.emplace_back(&CGI, &CGJ);
}
}
@@ -1801,7 +1803,7 @@ class AccessAnalysis {
const Loop *TheLoop;
/// List of accesses that need a further dependence check.
- SmallVector<MemAccessInfo, 8> CheckDeps;
+ llvm::SmallVectorWithFlags<MemAccessInfo, 8> CheckDeps;
/// Set of pointers that are read only.
SmallPtrSet<Value*, 16> ReadOnlyPtr;
@@ -1834,7 +1836,8 @@ class AccessAnalysis {
/// memcheck analysis without dependency checking
/// (i.e. ShouldRetryWithRuntimeChecks), isDependencyCheckNeeded is
/// cleared while this remains set if we have potentially dependent accesses.
- bool IsRTCheckAnalysisNeeded = false;
+ bool getIsRTCheckAnalysisNeeded() const { return CheckDeps.getFlag(0); }
+ void setIsRTCheckAnalysisNeeded(bool Value) { CheckDeps.setFlag(0, Value); }
/// The SCEV predicate containing all the SCEV-related assumptions.
PredicatedScalarEvolution &PSE;
@@ -2262,7 +2265,8 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
bool CanDoRT = true;
bool MayNeedRTCheck = false;
- if (!IsRTCheckAnalysisNeeded) return true;
+ if (!getIsRTCheckAnalysisNeeded())
+ return true;
if (auto *Deps = DepChecker.getDependences()) {
// If there are unknown dependences, this means runtime checks are needed to
@@ -2444,11 +2448,12 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
// If we can do run-time checks, but there are no checks, no runtime checks
// are needed. This can happen when all pointers point to the same underlying
// object for example.
- RtCheck.Need = CanDoRT ? RtCheck.getNumberOfChecks() != 0 : MayNeedRTCheck;
+ RtCheck.setNeedsChecking(CanDoRT ? RtCheck.getNumberOfChecks() != 0
+ : MayNeedRTCheck);
- bool CanDoRTIfNeeded = !RtCheck.Need || CanDoRT;
+ bool CanDoRTIfNeeded = !RtCheck.needsChecking() || CanDoRT;
assert(CanDoRTIfNeeded == (CanDoRT || !MayNeedRTCheck) &&
- "CanDoRTIfNeeded depends on RtCheck.Need");
+ "CanDoRTIfNeeded depends on RtCheck.needsChecking()");
if (!CanDoRTIfNeeded && !AllowPartial)
RtCheck.reset();
return CanDoRTIfNeeded;
@@ -2538,7 +2543,7 @@ void AccessAnalysis::buildDependenceSets() {
// catch "a[i] = a[i] + " without having to do a dependence check).
if ((IsWrite || IsReadOnlyPtr) && AliasSetHasWrite) {
CheckDeps.push_back(Access);
- IsRTCheckAnalysisNeeded = true;
+ setIsRTCheckAnalysisNeeded(true);
}
if (IsWrite)
@@ -3110,7 +3115,7 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
// TODO: Historically, we didn't retry with runtime checks when (unscaled)
// strides were different but there is no inherent reason to.
if (!isa<SCEVConstant>(Dist))
- ShouldRetryWithRuntimeChecks |= StrideAPtrInt == StrideBPtrInt;
+ InstMap.setFlag(0, InstMap.getFlag(0) || StrideAPtrInt == StrideBPtrInt);
// If distance is a SCEVCouldNotCompute, return Unknown immediately.
if (isa<SCEVCouldNotCompute>(Dist)) {
@@ -3405,18 +3410,18 @@ bool MemoryDepChecker::areDepsSafe(const DepCandidates &DepCands,
// dependences. In that case return as soon as we find the first
// unsafe dependence. This puts a limit on this quadratic
// algorithm.
- if (RecordDependences) {
+ if (recordDependences()) {
if (Type != Dependence::NoDep)
Dependences.emplace_back(A.second, B.second, Type);
if (Dependences.size() >= MaxDependences) {
- RecordDependences = false;
+ InstMap.setFlag(1, true);
Dependences.clear();
LLVM_DEBUG(dbgs()
<< "Too many dependences, stopped recording\n");
}
}
- if (!RecordDependences && !isSafeForVectorization())
+ if (!recordDependences() && !isSafeForVectorization())
return false;
}
++OI;
@@ -3453,9 +3458,8 @@ const char *MemoryDepChecker::Dependence::DepName[] = {
"BackwardVectorizable",
"BackwardVectorizableButPreventsForwarding"};
-void MemoryDepChecker::Dependence::print(
- raw_ostream &OS, unsigned Depth,
- const SmallVectorImpl<Instruction *> &Instrs) const {
+void MemoryDepChecker::Dependence::print(raw_ostream &OS, unsigned Depth,
+ ArrayRef<Instruction *> Instrs) const {
OS.indent(Depth) << DepName[Type] << ":\n";
OS.indent(Depth + 2) << *Instrs[Source] << " -> \n";
OS.indent(Depth + 2) << *Instrs[Destination] << "\n";
@@ -3517,7 +3521,7 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
HasConvergentOp = false;
PtrRtChecking->Pointers.clear();
- PtrRtChecking->Need = false;
+ PtrRtChecking->setNeedsChecking(false);
const bool IsAnnotatedParallel = TheLoop->isAnnotatedParallel();
@@ -3776,7 +3780,7 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
LLVM_DEBUG(dbgs() << "LAA: Retrying with memory checks\n");
PtrRtChecking->reset();
- PtrRtChecking->Need = true;
+ PtrRtChecking->setNeedsChecking(true);
UncomputablePtr = nullptr;
HasCompletePtrRtChecking = Accesses.canCheckPtrAtRT(
@@ -3829,7 +3833,7 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
if (DepsAreSafe) {
LLVM_DEBUG(
dbgs() << "LAA: No unsafe dependent memory operations in loop. We"
- << (PtrRtChecking->Need ? "" : " don't")
+ << (PtrRtChecking->needsChecking() ? "" : " don't")
<< " need runtime memory checks.\n");
return true;
}
@@ -4121,7 +4125,7 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
OS << ", with a maximum safe store-load forward width of " << SLDist
<< " bits";
}
- if (PtrRtChecking->Need)
+ if (PtrRtChecking->needsChecking())
OS << " with run-time checks";
OS << "\n";
}
@@ -4143,7 +4147,7 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
// List the pair of accesses need run-time checks to prove independence.
PtrRtChecking->print(OS, Depth);
- if (PtrRtChecking->Need && !HasCompletePtrRtChecking)
+ if (PtrRtChecking->needsChecking() && !HasCompletePtrRtChecking)
OS.indent(Depth) << "Generated run-time checks are incomplete\n";
OS << "\n";
diff --git a/llvm/lib/Analysis/LoopCacheAnalysis.cpp b/llvm/lib/Analysis/LoopCacheAnalysis.cpp
index 4954121aeabe1..6abba0342ffe0 100644
--- a/llvm/lib/Analysis/LoopCacheAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopCacheAnalysis.cpp
@@ -27,6 +27,7 @@
#include "llvm/Analysis/LoopCacheAnalysis.h"
#include "llvm/ADT/BreadthFirstIterator.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -127,7 +128,7 @@ static const SCEV *computeTripCount(const Loop &L, const SCEV &ElemSize,
// IndexedReference implementation
//
raw_ostream &llvm::operator<<(raw_ostream &OS, const IndexedReference &R) {
- if (!R.IsValid) {
+ if (!R.getIsValid()) {
OS << R.StoreOrLoadInst;
OS << ", IsValid=false.";
return OS;
@@ -150,8 +151,8 @@ IndexedReference::IndexedReference(Instruction &StoreOrLoadInst,
assert((isa<StoreInst>(StoreOrLoadInst) || isa<LoadInst>(StoreOrLoadInst)) &&
"Expecting a load or store instruction");
- IsValid = delinearize(LI);
- if (IsValid)
+ setIsValid(delinearize(LI));
+ if (getIsValid())
LLVM_DEBUG(dbgs().indent(2) << "Succesfully delinearized: " << *this
<< "\n");
}
@@ -159,7 +160,7 @@ IndexedReference::IndexedReference(Instruction &StoreOrLoadInst,
std::optional<bool>
IndexedReference::hasSpacialReuse(const IndexedReference &Other, unsigned CLS,
AAResults &AA) const {
- assert(IsValid && "Expecting a valid reference");
+ assert(getIsValid() && "Expecting a valid reference");
if (BasePointer != Other.getBasePointer() && !isAliased(Other, AA)) {
LLVM_DEBUG(dbgs().indent(2)
@@ -215,7 +216,7 @@ std::optional<bool>
IndexedReference::hasTemporalReuse(const IndexedReference &Other,
unsigned MaxDistance, const Loop &L,
DependenceInfo &DI, AAResults &AA) const {
- assert(IsValid && "Expecting a valid reference");
+ assert(getIsValid() && "Expecting a valid reference");
if (BasePointer != Other.getBasePointer() && !isAliased(Other, AA)) {
LLVM_DEBUG(dbgs().indent(2)
@@ -271,7 +272,7 @@ IndexedReference::hasTemporalReuse(const IndexedReference &Other,
CacheCostTy IndexedReference::computeRefCost(const Loop &L,
unsigned CLS) const {
- assert(IsValid && "Expecting a valid reference");
+ assert(getIsValid() && "Expecting a valid reference");
LLVM_DEBUG({
dbgs().indent(2) << "Computing cache cost for:\n";
dbgs().indent(4) << *this << "\n";
@@ -361,12 +362,16 @@ CacheCostTy IndexedReference::computeRefCost(const Loop &L,
bool IndexedReference::delinearize(const LoopInfo &LI) {
assert(Subscripts.empty() && "Subscripts should be empty");
assert(Sizes.empty() && "Sizes should be empty");
- assert(!IsValid && "Should be called once from the constructor");
+ assert(!getIsValid() && "Should be called once from the constructor");
LLVM_DEBUG(dbgs() << "Delinearizing: " << StoreOrLoadInst << "\n");
const SCEV *ElemSize = SE.getElementSize(&StoreOrLoadInst);
const BasicBlock *BB = StoreOrLoadInst.getParent();
+ SmallVector<const SCEV *, 3> DimensionSizes;
+ DimensionSizes = std::move(Sizes);
+ auto RestoreSizes =
+ scope_exit([&] { Sizes.assign(std::move(DimensionSizes)); });
if (Loop *L = LI.getLoopFor(BB)) {
const SCEV *AccessFn =
SE.getSCEVAtScope(getPointerOperand(&StoreOrLoadInst), L);
@@ -383,7 +388,8 @@ bool IndexedReference::delinearize(const LoopInfo &LI) {
AccessFn = SE.getMinusSCEV(AccessFn, BasePointer);
// Try to delinearize fixed-size arrays.
- if (delinearizeFixedSizeArray(SE, AccessFn, Subscripts, Sizes, ElemSize)) {
+ if (delinearizeFixedSizeArray(SE, AccessFn, Subscripts, DimensionSizes,
+ ElemSize)) {
IsFixedSize = true;
LLVM_DEBUG(dbgs().indent(2) << "In Loop '" << L->getName()
<< "', AccessFn: " << *AccessFn << "\n");
@@ -393,20 +399,20 @@ bool IndexedReference::delinearize(const LoopInfo &LI) {
if (!IsFixedSize) {
LLVM_DEBUG(dbgs().indent(2) << "In Loop '" << L->getName()
<< "', AccessFn: " << *AccessFn << "\n");
- Sizes.clear();
- llvm::delinearize(SE, AccessFn, Subscripts, Sizes,
+ DimensionSizes.clear();
+ llvm::delinearize(SE, AccessFn, Subscripts, DimensionSizes,
SE.getElementSize(&StoreOrLoadInst));
}
- if (Subscripts.empty() || Sizes.empty() ||
- Subscripts.size() != Sizes.size()) {
+ if (Subscripts.empty() || DimensionSizes.empty() ||
+ Subscripts.size() != DimensionSizes.size()) {
// Attempt to determine whether we have a single dimensional array access.
// before giving up.
if (!isOneDimensionalArray(*AccessFn, *ElemSize, *L, SE)) {
LLVM_DEBUG(dbgs().indent(2)
<< "ERROR: failed to delinearize reference\n");
Subscripts.clear();
- Sizes.clear();
+ DimensionSizes.clear();
return false;
}
@@ -424,7 +430,7 @@ bool IndexedReference::delinearize(const LoopInfo &LI) {
AccessFnAR->getLoop(), SCEVFlags::FlagNone);
const SCEV *Div = SE.getUDivExactExpr(AccessFn, ElemSize);
Subscripts.push_back(Div);
- Sizes.push_back(ElemSize);
+ DimensionSizes.push_back(ElemSize);
}
return all_of(Subscripts, [&](const SCEV *Subscript) {
diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp
index 37cea287284cd..fdcae635efe56 100644
--- a/llvm/lib/Analysis/MemorySSAUpdater.cpp
+++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/IteratedDominanceFrontier.h"
#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/MemorySSA.h"
@@ -56,15 +57,20 @@ MemoryAccess *MemorySSAUpdater::getPreviousDefIterative(
explicit StackFrame(BasicBlock *BB) : BB(BB), PredIt(pred_begin(BB)) {}
ResumePoint Resume = ResumePoint::EnterBlock;
// Multi-predecessor loop state.
- SmallVector<TrackingVH<MemoryAccess>, 4> PhiOps;
+ llvm::SmallVectorWithFlags<TrackingVH<MemoryAccess>, 4, 2> PhiOps;
// Cursor over BB's predecessors for the resumable RunPredLoop walk. This
// stays valid across suspend/resume because the walk only modifies
// MemorySSA, never terminators or CFG edges, so BB's predecessor list does
// not change.
pred_iterator PredIt;
// When set, `Returned` holds the result for the predecessor at PredIt.
- bool PendingIncoming = false;
- bool UniqueIncomingAccess = true;
+ bool getPendingIncoming() const { return PhiOps.getFlag(0); }
+ void setPendingIncoming(bool Value) { PhiOps.setFlag(0, Value); }
+ bool getUniqueIncomingAccess() const { return !PhiOps.getFlag(1); }
+ bool setUniqueIncomingAccess(bool Value) {
+ PhiOps.setFlag(1, !Value);
+ return Value;
+ }
MemoryAccess *SingleAccess = nullptr;
// Fold an incoming predecessor access into this frame's phi operands,
@@ -74,7 +80,7 @@ MemoryAccess *MemorySSAUpdater::getPreviousDefIterative(
if (!SingleAccess)
SingleAccess = Incoming;
else if (Incoming != SingleAccess)
- UniqueIncomingAccess = false;
+ setUniqueIncomingAccess(false);
PhiOps.push_back(Incoming);
}
};
@@ -166,10 +172,10 @@ MemoryAccess *MemorySSAUpdater::getPreviousDefIterative(
// Get the values in our predecessors for placement of a potential phi
// node. This will insert phi nodes if we cycle in order to break the
// cycle and have an operand.
- if (F.PendingIncoming) {
+ if (F.getPendingIncoming()) {
// Returned holds the result for the predecessor at PredIt.
F.incorporate(Returned);
- F.PendingIncoming = false;
+ F.setPendingIncoming(false);
++F.PredIt;
}
@@ -181,7 +187,7 @@ MemoryAccess *MemorySSAUpdater::getPreviousDefIterative(
if (MemoryAccess *IncomingAccess = GetLocalDefFromEnd(Pred)) {
F.incorporate(IncomingAccess);
} else {
- F.PendingIncoming = true;
+ F.setPendingIncoming(true);
WorkStack.emplace_back(Pred);
Suspended = true;
break;
@@ -200,7 +206,7 @@ MemoryAccess *MemorySSAUpdater::getPreviousDefIterative(
// See if we can avoid the phi by simplifying it.
auto *Result = tryRemoveTrivialPhi(Phi, F.PhiOps);
// If we couldn't simplify, we may have to create a phi
- if (Result == Phi && F.UniqueIncomingAccess && F.SingleAccess) {
+ if (Result == Phi && F.getUniqueIncomingAccess() && F.SingleAccess) {
// A concrete Phi only exists if we created an empty one to break a
// cycle.
if (Phi) {
@@ -209,7 +215,8 @@ MemoryAccess *MemorySSAUpdater::getPreviousDefIterative(
removeMemoryAccess(Phi);
}
Result = F.SingleAccess;
- } else if (Result == Phi && !(F.UniqueIncomingAccess && F.SingleAccess)) {
+ } else if (Result == Phi &&
+ !(F.getUniqueIncomingAccess() && F.SingleAccess)) {
if (!Phi)
Phi = MSSA->createMemoryPhi(CurBB);
diff --git a/llvm/lib/Analysis/PtrUseVisitor.cpp b/llvm/lib/Analysis/PtrUseVisitor.cpp
index 9c79546f491ef..2d4e1eac4513f 100644
--- a/llvm/lib/Analysis/PtrUseVisitor.cpp
+++ b/llvm/lib/Analysis/PtrUseVisitor.cpp
@@ -21,16 +21,14 @@ void detail::PtrUseVisitorBase::enqueueUsers(Value &I) {
for (Use &U : I.uses()) {
if (VisitedUses.insert(&U).second) {
UseToVisit NewU = {
- UseToVisit::UseAndIsOffsetKnownPair(&U, IsOffsetKnown),
- Offset
- };
+ UseToVisit::UseAndIsOffsetKnownPair(&U, isOffsetKnown()), Offset};
Worklist.push_back(std::move(NewU));
}
}
}
bool detail::PtrUseVisitorBase::adjustOffsetForGEP(GetElementPtrInst &GEPI) {
- if (!IsOffsetKnown)
+ if (!isOffsetKnown())
return false;
APInt TmpOffset(DL.getIndexTypeSizeInBits(GEPI.getType()), 0);
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 38b3b20baeb16..a86f9db644275 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8920,7 +8920,8 @@ bool ScalarEvolution::BackedgeTakenInfo::isConstantMaxOrZero(
auto PredicateNotAlwaysTrue = [](const ExitNotTakenInfo &ENT) {
return !ENT.hasAlwaysTruePredicate();
};
- return MaxOrZero && !any_of(ExitNotTaken, PredicateNotAlwaysTrue);
+ return ExitNotTaken.getFlag(1) &&
+ !any_of(ExitNotTaken, PredicateNotAlwaysTrue);
}
ScalarEvolution::ExitLimit::ExitLimit(const SCEV *E)
@@ -8931,7 +8932,8 @@ ScalarEvolution::ExitLimit::ExitLimit(
const SCEV *SymbolicMaxNotTaken, bool MaxOrZero,
ArrayRef<ArrayRef<const SCEVPredicate *>> PredLists)
: ExactNotTaken(E), ConstantMaxNotTaken(ConstantMaxNotTaken),
- SymbolicMaxNotTaken(SymbolicMaxNotTaken), MaxOrZero(MaxOrZero) {
+ SymbolicMaxNotTaken(SymbolicMaxNotTaken) {
+ Predicates.setFlag(0, MaxOrZero);
// If we prove the max count is zero, so is the symbolic bound. This happens
// in practice due to differences in a) how context sensitive we've chosen
// to be and b) how we reason about bounds implied by UB.
@@ -8981,7 +8983,8 @@ ScalarEvolution::ExitLimit::ExitLimit(const SCEV *E,
ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo(
ArrayRef<ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo> ExitCounts,
bool IsComplete, const SCEV *ConstantMax, bool MaxOrZero)
- : ConstantMax(ConstantMax), IsComplete(IsComplete), MaxOrZero(MaxOrZero) {
+ : ConstantMax(ConstantMax) {
+ ExitNotTaken.setFlags(unsigned(IsComplete) | (unsigned(MaxOrZero) << 1));
using EdgeExitInfo = ScalarEvolution::BackedgeTakenInfo::EdgeExitInfo;
ExitNotTaken.reserve(ExitCounts.size());
@@ -9068,7 +9071,7 @@ ScalarEvolution::computeBackedgeTakenCount(const Loop *L,
DT.dominates(ExitBB, Latch)) {
if (!MustExitMaxBECount) {
MustExitMaxBECount = EL.ConstantMaxNotTaken;
- MustExitMaxOrZero = EL.MaxOrZero;
+ MustExitMaxOrZero = EL.isMaxOrZero();
} else {
MustExitMaxBECount = getUMinFromMismatchedTypes(MustExitMaxBECount,
EL.ConstantMaxNotTaken);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 60b7824342aa3..7e74ca9beec54 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -294,7 +294,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
// We should have already returned an error if we observed both intrinsics and
// records in this IR.
- assert(!(SeenNewDbgInfoFormat && SeenOldDbgInfoFormat) &&
+ assert(!(getSeenNewDbgInfoFormat() && getSeenOldDbgInfoFormat()) &&
"Mixed debug intrinsics/records seen without a parsing error?");
// Handle any function attribute group forward references.
@@ -7550,10 +7550,10 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
// following the debug records, i.e. they cannot appear after the block
// terminator.
while (Lex.getKind() == lltok::hash) {
- if (SeenOldDbgInfoFormat)
+ if (getSeenOldDbgInfoFormat())
return error(Lex.getLoc(), "debug record should not appear in a module "
"containing debug info intrinsics");
- SeenNewDbgInfoFormat = true;
+ setSeenNewDbgInfoFormat(true);
Lex.Lex();
DbgRecord *DR;
@@ -9054,12 +9054,12 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
if (CalleeID.Kind == ValID::t_GlobalName &&
isOldDbgFormatIntrinsic(CalleeID.StrVal)) {
- if (SeenNewDbgInfoFormat) {
+ if (getSeenNewDbgInfoFormat()) {
CI->deleteValue();
return error(CallLoc, "llvm.dbg intrinsic should not appear in a module "
"using non-intrinsic debug info");
}
- SeenOldDbgInfoFormat = true;
+ setSeenOldDbgInfoFormat(true);
}
CI->setAttributes(PAL);
ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index bad71316e3dce..65459855b1c86 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitcodeCommon.h"
@@ -590,7 +591,8 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
uint64_t NextUnreadBit = 0;
// Last function offset found in the VST.
uint64_t LastFunctionBlockBit = 0;
- bool SeenValueSymbolTable = false;
+ bool getSeenValueSymbolTable() const { return SSIDs.getFlag(0); }
+ void setSeenValueSymbolTable(bool Value) { SSIDs.setFlag(0, Value); }
uint64_t VSTOffset = 0;
std::vector<std::string> SectionTable;
@@ -617,7 +619,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
std::optional<MetadataLoader> MDLoader;
std::vector<Comdat *> ComdatList;
DenseSet<GlobalObject *> ImplicitComdatObjects;
- SmallVector<Instruction *, 64> InstructionList;
+ llvm::SmallVectorWithFlags<Instruction *, 64, 4> InstructionList;
std::vector<std::pair<GlobalVariable *, unsigned>> GlobalInits;
std::vector<std::pair<GlobalValue *, unsigned>> IndirectSymbolInits;
@@ -652,7 +654,8 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
// Several operations happen after the module header has been read, but
// before function bodies are processed. This keeps track of whether
// we've done this yet.
- bool SeenFirstFunctionBody = false;
+ bool getSeenFirstFunctionBody() const { return SSIDs.getFlag(1); }
+ void setSeenFirstFunctionBody(bool Value) { SSIDs.setFlag(1, Value); }
/// When function bodies are initially scanned, this map contains info about
/// where to find deferred function body in the stream.
@@ -682,22 +685,30 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
/// operands are not relative to the instruction ID: basic block numbers, and
/// types. Once the old style function blocks have been phased out, we would
/// not need this flag.
- bool UseRelativeIDs = false;
+ bool getUseRelativeIDs() const { return SSIDs.getFlag(2); }
+ void setUseRelativeIDs(bool Value) { SSIDs.setFlag(2, Value); }
/// True if all functions will be materialized, negating the need to process
/// (e.g.) blockaddress forward references.
- bool WillMaterializeAllForwardRefs = false;
+ bool getWillMaterializeAllForwardRefs() const { return SSIDs.getFlag(3); }
+ void setWillMaterializeAllForwardRefs(bool Value) { SSIDs.setFlag(3, Value); }
/// Tracks whether we have seen debug intrinsics or records in this bitcode;
/// seeing both in a single module is currently a fatal error.
- bool SeenDebugIntrinsic = false;
- bool SeenDebugRecord = false;
+ bool getSeenDebugIntrinsic() const { return InstructionList.getFlag(0); }
+ bool setSeenDebugIntrinsic(bool Value) {
+ InstructionList.setFlag(0, Value);
+ return Value;
+ }
+ bool getSeenDebugRecord() const { return InstructionList.getFlag(1); }
+ void setSeenDebugRecord(bool Value) { InstructionList.setFlag(1, Value); }
- bool StripDebugInfo = false;
+ bool getStripDebugInfoFlag() const { return InstructionList.getFlag(2); }
+ void setStripDebugInfoFlag(bool Value) { InstructionList.setFlag(2, Value); }
TBAAVerifier TBAAVerifyHelper;
std::vector<std::string> BundleTags;
- SmallVector<SyncScope::ID, 8> SSIDs;
+ llvm::SmallVectorWithFlags<SyncScope::ID, 8, 4> SSIDs;
std::optional<ValueTypeCallbackTy> ValueTypeCallback;
@@ -708,7 +719,12 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
/// intrinsic calls (llvm.dbg.*) are not auto-upgraded to non-instruction
/// debug records by globalCleanup(); the caller is expected to perform the
/// upgrade manually after any custom processing.
- bool SkipDebugIntrinsicUpgrade = false;
+ bool getSkipDebugIntrinsicUpgrade() const {
+ return InstructionList.getFlag(3);
+ }
+ void setSkipDebugIntrinsicUpgrade(bool Value) {
+ InstructionList.setFlag(3, Value);
+ }
public:
BitcodeReader(BitstreamCursor Stream, StringRef Strtab,
@@ -779,7 +795,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
if (Slot == Record.size()) return true;
unsigned ValNo = (unsigned)Record[Slot++];
// Adjust the ValNo, if it was encoded relative to the InstNum.
- if (UseRelativeIDs)
+ if (getUseRelativeIDs())
ValNo = InstNum - ValNo;
if (ValNo < InstNum) {
// If this is not a forward reference, just return the value we already
@@ -846,7 +862,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)Record[Slot];
// Adjust the ValNo, if it was encoded relative to the InstNum.
- if (UseRelativeIDs)
+ if (getUseRelativeIDs())
ValNo = InstNum - ValNo;
return getFnValueByID(ValNo, Ty, TyID, ConstExprInsertBB);
}
@@ -858,7 +874,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]);
// Adjust the ValNo, if it was encoded relative to the InstNum.
- if (UseRelativeIDs)
+ if (getUseRelativeIDs())
ValNo = InstNum - ValNo;
return getFnValueByID(ValNo, Ty, TyID, ConstExprInsertBB);
}
@@ -1101,11 +1117,11 @@ BitcodeReader::BitcodeReader(BitstreamCursor Stream, StringRef Strtab,
}
Error BitcodeReader::materializeForwardReferencedFunctions() {
- if (WillMaterializeAllForwardRefs)
+ if (getWillMaterializeAllForwardRefs())
return Error::success();
// Prevent recursion.
- WillMaterializeAllForwardRefs = true;
+ setWillMaterializeAllForwardRefs(true);
while (!BasicBlockFwdRefQueue.empty()) {
Function *F = BasicBlockFwdRefQueue.front();
@@ -1134,7 +1150,7 @@ Error BitcodeReader::materializeForwardReferencedFunctions() {
BackwardRefFunctions.clear();
// Reset state.
- WillMaterializeAllForwardRefs = false;
+ setWillMaterializeAllForwardRefs(false);
return Error::success();
}
@@ -4045,7 +4061,7 @@ Error BitcodeReader::materializeMetadata() {
return Error::success();
}
-void BitcodeReader::setStripDebugInfo() { StripDebugInfo = true; }
+void BitcodeReader::setStripDebugInfo() { setStripDebugInfoFlag(true); }
/// When we see the block for a function body, remember where it is and then
/// skip it. This lets us lazily deserialize the functions.
@@ -4084,7 +4100,7 @@ Error BitcodeReader::globalCleanup() {
Function *NewFn;
if (UpgradeIntrinsicFunction(&F,
NewFn, /*CanUpgradeDebugIntrinsicsToRecords=*/
- !SkipDebugIntrinsicUpgrade))
+ !getSkipDebugIntrinsicUpgrade()))
UpgradedIntrinsics[&F] = NewFn;
// Look for functions that rely on old function attribute behavior.
UpgradeFunctionAttributes(F);
@@ -4127,12 +4143,12 @@ Error BitcodeReader::rememberAndSkipFunctionBodies() {
if (Stream.AtEndOfStream())
return error("Could not find function in stream");
- if (!SeenFirstFunctionBody)
+ if (!getSeenFirstFunctionBody())
return error("Trying to materialize functions before seeing function blocks");
// An old bitcode file with the symbol table at the end would have
// finished the parse greedily.
- assert(SeenValueSymbolTable);
+ assert(getSeenValueSymbolTable());
while (true) {
Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance();
@@ -4709,7 +4725,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
return Err;
break;
case bitc::VALUE_SYMTAB_BLOCK_ID:
- if (!SeenValueSymbolTable) {
+ if (!getSeenValueSymbolTable()) {
// Either this is an old form VST without function index and an
// associated VST forward declaration record (which would have caused
// the VST to be jumped to and parsed before it was encountered
@@ -4718,7 +4734,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
assert(VSTOffset == 0 || FunctionsWithBodies.empty());
if (Error Err = parseValueSymbolTable())
return Err;
- SeenValueSymbolTable = true;
+ setSeenValueSymbolTable(true);
} else {
// We must have had a VST forward declaration record, which caused
// the parser to jump to and parse the VST earlier.
@@ -4753,21 +4769,21 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
// If this is the first function body we've seen, reverse the
// FunctionsWithBodies list.
- if (!SeenFirstFunctionBody) {
+ if (!getSeenFirstFunctionBody()) {
std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
if (Error Err = globalCleanup())
return Err;
- SeenFirstFunctionBody = true;
+ setSeenFirstFunctionBody(true);
}
if (VSTOffset > 0) {
// If we have a VST forward declaration record, make sure we
// parse the VST now if we haven't already. It is needed to
// set up the DeferredFunctionInfo vector for lazy reading.
- if (!SeenValueSymbolTable) {
+ if (!getSeenValueSymbolTable()) {
if (Error Err = BitcodeReader::parseValueSymbolTable(VSTOffset))
return Err;
- SeenValueSymbolTable = true;
+ setSeenValueSymbolTable(true);
// Fall through so that we record the NextUnreadBit below.
// This is necessary in case we have an anonymous function that
// is later materialized. Since it will not have a VST entry we
@@ -4796,7 +4812,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
// materialization calls will resume it when necessary. If the bitcode
// file is old, the symbol table will be at the end instead and will not
// have been seen yet. In this case, just finish the parse now.
- if (SeenValueSymbolTable) {
+ if (getSeenValueSymbolTable()) {
NextUnreadBit = Stream.GetCurrentBitNo();
// After the VST has been parsed, we need to make sure intrinsic name
// are auto-upgraded.
@@ -4833,7 +4849,7 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit,
Expected<unsigned> VersionOrErr = parseVersionRecord(Record);
if (!VersionOrErr)
return VersionOrErr.takeError();
- UseRelativeIDs = *VersionOrErr >= 1;
+ setUseRelativeIDs(*VersionOrErr >= 1);
break;
}
case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
@@ -4960,7 +4976,7 @@ Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata,
};
MDCallbacks.MDType = Callbacks.MDType;
MDLoader = MetadataLoader(Stream, *M, ValueList, IsImporting, MDCallbacks);
- SkipDebugIntrinsicUpgrade = Callbacks.SkipDebugIntrinsicUpgrade;
+ setSkipDebugIntrinsicUpgrade(Callbacks.SkipDebugIntrinsicUpgrade);
return parseModule(0, ShouldLazyLoadMetadata, Callbacks);
}
@@ -6335,7 +6351,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
// negative IDs (for forward references). Use a signed VBR
// representation to keep the encoding small.
Value *V;
- if (UseRelativeIDs)
+ if (getUseRelativeIDs())
V = getValueSigned(Record, i * 2 + 1, NextValueNo, Ty, TyID, EdgeBB);
else
V = getValue(Record, i * 2 + 1, NextValueNo, Ty, TyID, EdgeBB);
@@ -6859,7 +6875,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
case bitc::FUNC_CODE_DEBUG_RECORD_LABEL: {
// DbgLabelRecords are placed after the Instructions that they are
// attached to.
- SeenDebugRecord = true;
+ setSeenDebugRecord(true);
Instruction *Inst = getLastInstruction();
if (!Inst)
return error("Invalid dbg record: missing instruction");
@@ -6876,7 +6892,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: {
// DbgVariableRecords are placed after the Instructions that they are
// attached to.
- SeenDebugRecord = true;
+ setSeenDebugRecord(true);
Instruction *Inst = getLastInstruction();
if (!Inst)
return error("Invalid dbg record: missing instruction");
@@ -7045,7 +7061,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
cast<CallInst>(I)->setTailCallKind(TCK);
cast<CallInst>(I)->setAttributes(PAL);
if (isa<DbgInfoIntrinsic>(I))
- SeenDebugIntrinsic = true;
+ setSeenDebugIntrinsic(true);
if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(I)) {
unsigned ArgNo = Intrinsic::NoAliasScopeDeclScopeArg;
if (auto *ListAsValue =
@@ -7248,10 +7264,10 @@ Error BitcodeReader::materialize(GlobalValue *GV) {
// All parsed Functions should load into the debug info format dictated by the
// Module.
- if (SeenDebugIntrinsic && SeenDebugRecord)
+ if (getSeenDebugIntrinsic() && getSeenDebugRecord())
return error("Mixed debug intrinsics and debug records in bitcode module!");
- if (StripDebugInfo)
+ if (getStripDebugInfoFlag())
stripDebugInfo(*F);
// Finish fn->subprogram upgrade for materialized functions.
@@ -7343,7 +7359,7 @@ Error BitcodeReader::materializeModule() {
return Err;
// Promise to materialize all forward references.
- WillMaterializeAllForwardRefs = true;
+ setWillMaterializeAllForwardRefs(true);
// Iterate over the module, deserializing any functions that are still on
// disk.
diff --git a/llvm/lib/CAS/OnDiskGraphDB.cpp b/llvm/lib/CAS/OnDiskGraphDB.cpp
index ffec3c3dbe8ae..a204242f45d94 100644
--- a/llvm/lib/CAS/OnDiskGraphDB.cpp
+++ b/llvm/lib/CAS/OnDiskGraphDB.cpp
@@ -48,6 +48,7 @@
#include "OnDiskCommon.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ScopeExit.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CAS/OnDiskCASLogger.h"
#include "llvm/CAS/OnDiskDataAllocator.h"
@@ -437,11 +438,11 @@ using StandaloneDataMapTy = StandaloneDataMap<16>;
class InternalRefVector {
public:
void push_back(InternalRef Ref) {
- if (NeedsFull)
+ if (getNeedsFull())
return FullRefs.push_back(Ref);
if (std::optional<InternalRef4B> Small = InternalRef4B::tryToShrink(Ref))
return SmallRefs.push_back(*Small);
- NeedsFull = true;
+ setNeedsFull(true);
assert(FullRefs.empty());
FullRefs.reserve(SmallRefs.size() + 1);
for (InternalRef4B Small : SmallRefs)
@@ -452,14 +453,15 @@ class InternalRefVector {
operator InternalRefArrayRef() const {
assert(SmallRefs.empty() || FullRefs.empty());
- return NeedsFull ? InternalRefArrayRef(FullRefs)
- : InternalRefArrayRef(SmallRefs);
+ return getNeedsFull() ? InternalRefArrayRef(FullRefs)
+ : InternalRefArrayRef(SmallRefs);
}
private:
- bool NeedsFull = false;
+ bool getNeedsFull() const { return FullRefs.getFlag(0); }
+ void setNeedsFull(bool Value) { FullRefs.setFlag(0, Value); }
SmallVector<InternalRef4B> SmallRefs;
- SmallVector<InternalRef> FullRefs;
+ llvm::SmallVectorWithFlags<InternalRef> FullRefs;
};
} // namespace
diff --git a/llvm/lib/CGData/StableFunctionMap.cpp b/llvm/lib/CGData/StableFunctionMap.cpp
index b8b8cfd1286ae..5e2bd4b6bb7d5 100644
--- a/llvm/lib/CGData/StableFunctionMap.cpp
+++ b/llvm/lib/CGData/StableFunctionMap.cpp
@@ -41,7 +41,7 @@ std::optional<std::string> StableFunctionMap::getNameForId(unsigned Id) const {
}
void StableFunctionMap::insert(const StableFunction &Func) {
- assert(!Finalized && "Cannot insert after finalization");
+ assert(!isFinalized() && "Cannot insert after finalization");
auto FuncNameId = getIdOrCreateForName(Func.FunctionName);
auto ModuleNameId = getIdOrCreateForName(Func.ModuleName);
auto IndexOperandHashMap = std::make_unique<IndexOperandHashMapType>();
@@ -54,7 +54,7 @@ void StableFunctionMap::insert(const StableFunction &Func) {
}
void StableFunctionMap::merge(const StableFunctionMap &OtherMap) {
- assert(!Finalized && "Cannot merge after finalization");
+ assert(!isFinalized() && "Cannot merge after finalization");
deserializeLazyLoadingEntries();
for (auto &[Hash, Funcs] : OtherMap.HashToFuncs) {
auto &ThisFuncs = HashToFuncs[Hash].Entries;
@@ -258,5 +258,5 @@ void StableFunctionMap::finalize(bool SkipTrim) {
for (auto It : ToDelete)
HashToFuncs.erase(It);
- Finalized = true;
+ IdToName.setFlag(0, true);
}
diff --git a/llvm/lib/CGData/StableFunctionMapRecord.cpp b/llvm/lib/CGData/StableFunctionMapRecord.cpp
index 4840a9b906f26..5473a1d8708c6 100644
--- a/llvm/lib/CGData/StableFunctionMapRecord.cpp
+++ b/llvm/lib/CGData/StableFunctionMapRecord.cpp
@@ -147,12 +147,12 @@ void StableFunctionMapRecord::deserializeEntry(const unsigned char *Ptr,
StableFunctionMap *FunctionMap) {
auto FunctionNameId =
endian::readNext<uint32_t, endianness::little, unaligned>(Ptr);
- if (FunctionMap->ReadStableFunctionMapNames)
+ if (FunctionMap->readStableFunctionMapNames())
assert(FunctionMap->getNameForId(FunctionNameId) &&
"FunctionNameId out of range");
auto ModuleNameId =
endian::readNext<uint32_t, endianness::little, unaligned>(Ptr);
- if (FunctionMap->ReadStableFunctionMapNames)
+ if (FunctionMap->readStableFunctionMapNames())
assert(FunctionMap->getNameForId(ModuleNameId) &&
"ModuleNameId out of range");
auto InstCount =
@@ -200,7 +200,7 @@ void StableFunctionMapRecord::deserialize(const unsigned char *&Ptr,
const auto NamesByteSize =
endian::readNext<uint64_t, endianness::little, unaligned>(Ptr);
const auto NamesOffset = reinterpret_cast<uintptr_t>(Ptr);
- if (FunctionMap->ReadStableFunctionMapNames) {
+ if (FunctionMap->readStableFunctionMapNames()) {
for (unsigned I = 0; I < NumNames; ++I) {
StringRef Name(reinterpret_cast<const char *>(Ptr));
Ptr += Name.size() + 1;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
index ec28ba8c8efd7..0842b794b2898 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
@@ -15,6 +15,7 @@
#include "DwarfUnit.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
@@ -204,7 +205,7 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
/// FoldingSet that uniques the abbreviations.
FoldingSet<DebugNamesAbbrev> AbbreviationsSet;
/// Vector containing DebugNames abbreviations for iteration in order.
- SmallVector<DebugNamesAbbrev *, 5> AbbreviationsVector;
+ llvm::SmallVectorWithFlags<DebugNamesAbbrev *, 5> AbbreviationsVector;
/// The bump allocator to use when creating DIEAbbrev objects in the uniqued
/// storage container.
BumpPtrAllocator Alloc;
@@ -218,7 +219,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
MCSymbol *AbbrevEnd = Asm->createTempSymbol("names_abbrev_end");
MCSymbol *EntryPool = Asm->createTempSymbol("names_entries");
// Indicates if this module is built with Split Dwarf enabled.
- bool IsSplitDwarf = false;
+ bool getIsSplitDwarf() const { return AbbreviationsVector.getFlag(0); }
+ void setIsSplitDwarf(bool Value) { AbbreviationsVector.setFlag(0, Value); }
/// Stores the DIE offsets which are indexed by this table.
DenseSet<OffsetAndUnitID> IndexedOffsets;
@@ -479,7 +481,7 @@ void Dwarf5AccelTableWriter::emitTUList() const {
Asm->OutStreamer->AddComment("Type unit " + Twine(TU.index()));
if (std::holds_alternative<MCSymbol *>(TU.value()))
Asm->emitDwarfSymbolReference(std::get<MCSymbol *>(TU.value()));
- else if (IsSplitDwarf)
+ else if (getIsSplitDwarf())
Asm->emitInt64(std::get<uint64_t>(TU.value()));
else
Asm->emitDwarfLengthOrOffset(std::get<uint64_t>(TU.value()));
@@ -637,9 +639,10 @@ Dwarf5AccelTableWriter::Dwarf5AccelTableWriter(
Header(CompUnits.size(), IsSplitDwarf ? 0 : TypeUnits.size(),
IsSplitDwarf ? TypeUnits.size() : 0, Contents.getBucketCount(),
Contents.getUniqueNameCount()),
+ AbbreviationsVector(decltype(this->AbbreviationsVector)::withFlags(
+ unsigned(IsSplitDwarf))),
CompUnits(CompUnits), TypeUnits(TypeUnits),
- getIndexForEntry(std::move(getIndexForEntry)),
- IsSplitDwarf(IsSplitDwarf) {
+ getIndexForEntry(std::move(getIndexForEntry)) {
for (auto &Bucket : Contents.getBuckets())
for (auto *Hash : Bucket)
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 2f699d2972504..77ab58b006e5f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -407,9 +407,9 @@ AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer,
OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)),
PointerSize(tm.getTargetTriple().getArchPointerBitWidth() / 8),
SM(*this) {
- VerboseAsm = OutStreamer->isVerboseAsm();
- DwarfUsesRelocationsAcrossSections =
- MAI.doesDwarfUseRelocationsAcrossSections();
+ setVerboseAsm(OutStreamer->isVerboseAsm());
+ setDwarfUsesRelocationsAcrossSectionsFlag(
+ MAI.doesDwarfUseRelocationsAcrossSections());
GetMMI = [this]() {
auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
return MMIWP ? &MMIWP->getMMI() : nullptr;
@@ -532,9 +532,9 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
bool AsmPrinter::doInitialization(Module &M) {
MMI = GetMMI();
PointerSize = M.getDataLayout().getPointerSize(0);
- HasSplitStack = false;
- HasNoSplitStack = false;
- DbgInfoAvailable = !M.debug_compile_units().empty();
+ setHasSplitStack(false);
+ setHasNoSplitStack(false);
+ setDbgInfoAvailable(!M.debug_compile_units().empty());
const Triple &Target = M.getTargetTriple();
AddrLabelSymbols = nullptr;
@@ -3157,10 +3157,10 @@ bool AsmPrinter::doFinalization(Module &M) {
// Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if
// split-stack is used.
- if (M.getTargetTriple().isOSBinFormatELF() && HasSplitStack) {
+ if (M.getTargetTriple().isOSBinFormatELF() && getHasSplitStack()) {
OutStreamer->switchSection(OutContext.getELFSection(".note.GNU-split-stack",
ELF::SHT_PROGBITS, 0));
- if (HasNoSplitStack)
+ if (getHasNoSplitStack())
OutStreamer->switchSection(OutContext.getELFSection(
".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0));
}
@@ -3242,12 +3242,12 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
// Record that there are split-stack functions, so we will emit a special
// section to tell the linker.
if (MF.shouldSplitStack()) {
- HasSplitStack = true;
+ setHasSplitStack(true);
if (!MF.getFrameInfo().needsSplitStackProlog())
- HasNoSplitStack = true;
+ setHasNoSplitStack(true);
} else
- HasNoSplitStack = true;
+ setHasNoSplitStack(true);
// Get the function symbol.
if (!MAI.isAIX()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 9cf268ce8ce4f..180e2d75a585d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -2997,10 +2997,9 @@ void CodeViewDebug::emitLexicalBlock(const LexicalBlock &Block,
/// Convenience routine for collecting lexical block information for a list
/// of lexical scopes.
void CodeViewDebug::collectLexicalBlockInfo(
- SmallVectorImpl<LexicalScope *> &Scopes,
- SmallVectorImpl<LexicalBlock *> &Blocks,
- SmallVectorImpl<LocalVariable> &Locals,
- SmallVectorImpl<CVGlobalVariable> &Globals) {
+ ArrayRef<LexicalScope *> Scopes, SmallVectorImpl<LexicalBlock *> &Blocks,
+ SmallVectorImpl<LocalVariable> &Locals,
+ SmallVectorImpl<CVGlobalVariable> &Globals) {
for (LexicalScope *Scope : Scopes)
collectLexicalBlockInfo(*Scope, Blocks, Locals, Globals);
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 9118394f2fe3b..ae6fc95cc5fc0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -411,7 +411,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
// Construct the lexical block tree for a routine, pruning emptpy lexical
// scopes, and populate it with local variables.
- void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes,
+ void collectLexicalBlockInfo(ArrayRef<LexicalScope *> Scopes,
SmallVectorImpl<LexicalBlock *> &Blocks,
SmallVectorImpl<LocalVariable> &Locals,
SmallVectorImpl<CVGlobalVariable> &Globals);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 5e659c7b7c621..dba67a520c749 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -122,7 +122,7 @@ void DebugHandlerBase::identifyScopeMarkers() {
while (!WorkList.empty()) {
LexicalScope *S = WorkList.pop_back_val();
- const SmallVectorImpl<LexicalScope *> &Children = S->getChildren();
+ ArrayRef<LexicalScope *> Children = S->getChildren();
if (!Children.empty())
WorkList.append(Children.begin(), Children.end());
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index ada7e9a7a9023..3836107fdf09f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -10,6 +10,7 @@
#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
#include "DebugLocStream.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
@@ -135,17 +136,21 @@ class DbgValueLoc {
/// Any complex address location expression for this DbgValueLoc.
const DIExpression *Expression;
- SmallVector<DbgValueLocEntry, 2> ValueLocEntries;
+ llvm::SmallVectorWithFlags<DbgValueLocEntry, 2> ValueLocEntries;
- bool IsVariadic;
+ bool getIsVariadic() const { return ValueLocEntries.getFlag(0); }
+ void setIsVariadic(bool Value) { ValueLocEntries.setFlag(0, Value); }
public:
DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs)
- : Expression(Expr), ValueLocEntries(Locs), IsVariadic(true) {}
+ : Expression(Expr),
+ ValueLocEntries(decltype(this->ValueLocEntries)::withFlags(1, Locs)) {}
DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs,
bool IsVariadic)
- : Expression(Expr), ValueLocEntries(Locs), IsVariadic(IsVariadic) {
+ : Expression(Expr),
+ ValueLocEntries(decltype(this->ValueLocEntries)::withFlags(
+ unsigned(IsVariadic), Locs)) {
#ifndef NDEBUG
assert(Expr->isValid() ||
!any_of(Locs, [](auto LE) { return LE.isLocation(); }));
@@ -156,22 +161,22 @@ class DbgValueLoc {
}
DbgValueLoc(const DIExpression *Expr, DbgValueLocEntry Loc)
- : Expression(Expr), ValueLocEntries(1, Loc), IsVariadic(false) {
+ : Expression(Expr), ValueLocEntries(1, Loc) {
assert(((Expr && Expr->isValid()) || !Loc.isLocation()) &&
"DBG_VALUE with a machine location must have a valid expression.");
}
bool isFragment() const { return getExpression()->isFragment(); }
bool isEntryVal() const { return getExpression()->isEntryValue(); }
- bool isVariadic() const { return IsVariadic; }
+ bool isVariadic() const { return getIsVariadic(); }
bool isEquivalent(const DbgValueLoc &Other) const {
// Cannot be equivalent with different numbers of entries.
if (ValueLocEntries.size() != Other.ValueLocEntries.size())
return false;
bool ThisIsIndirect =
- !IsVariadic && ValueLocEntries[0].isIndirectLocation();
+ !getIsVariadic() && ValueLocEntries[0].isIndirectLocation();
bool OtherIsIndirect =
- !Other.IsVariadic && Other.ValueLocEntries[0].isIndirectLocation();
+ !Other.getIsVariadic() && Other.ValueLocEntries[0].isIndirectLocation();
// Check equivalence of DIExpressions + Directness together.
if (!DIExpression::isEqualExpression(Expression, ThisIsIndirect,
Other.Expression, OtherIsIndirect))
@@ -185,7 +190,8 @@ class DbgValueLoc {
ThisOp.getLoc().getReg() == OtherOp.getLoc().getReg();
}
// If neither are indirect, then just compare the loc entries directly.
- return ValueLocEntries == Other.ValueLocEntries;
+ return (llvm::ArrayRef<llvm::DbgValueLocEntry>(ValueLocEntries) ==
+ llvm::ArrayRef<llvm::DbgValueLocEntry>(Other.ValueLocEntries));
}
const DIExpression *getExpression() const { return Expression; }
ArrayRef<DbgValueLocEntry> getLocEntries() const { return ValueLocEntries; }
@@ -297,8 +303,9 @@ inline bool operator==(const DbgValueLocEntry &A, const DbgValueLocEntry &B) {
/// Compare two DbgValueLocs for equality.
inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) {
- return A.ValueLocEntries == B.ValueLocEntries &&
- A.Expression == B.Expression && A.IsVariadic == B.IsVariadic;
+ return (llvm::ArrayRef<llvm::DbgValueLocEntry>(A.ValueLocEntries) ==
+ llvm::ArrayRef<llvm::DbgValueLocEntry>(B.ValueLocEntries)) &&
+ A.Expression == B.Expression && A.getIsVariadic() == B.getIsVariadic();
}
/// Compare two fragments based on their offset.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
index 6f553dc85c646..7a508c5fc6d12 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
@@ -12,6 +12,7 @@
#include "ByteStreamer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace llvm {
@@ -45,17 +46,20 @@ class DebugLocStream {
private:
SmallVector<List, 4> Lists;
- SmallVector<Entry, 32> Entries;
+ llvm::SmallVectorWithFlags<Entry, 32> Entries;
SmallString<256> DWARFBytes;
std::vector<std::string> Comments;
MCSymbol *Sym = nullptr;
/// Only verbose textual output needs comments. This will be set to
/// true for that case, and false otherwise.
- bool GenerateComments;
+ bool getGenerateComments() const { return Entries.getFlag(0); }
+ void setGenerateComments(bool Value) { Entries.setFlag(0, Value); }
public:
- DebugLocStream(bool GenerateComments) : GenerateComments(GenerateComments) { }
+ DebugLocStream(bool GenerateComments)
+ : Entries(
+ decltype(this->Entries)::withFlags(unsigned(GenerateComments))) {}
size_t getNumLists() const { return Lists.size(); }
const List &getList(size_t LI) const { return Lists[LI]; }
ArrayRef<List> getLists() const { return Lists; }
@@ -103,7 +107,7 @@ class DebugLocStream {
public:
BufferByteStreamer getStreamer() {
- return BufferByteStreamer(DWARFBytes, Comments, GenerateComments);
+ return BufferByteStreamer(DWARFBytes, Comments, getGenerateComments());
}
ArrayRef<Entry> getEntries(const List &L) const {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index ee52dca4803ae..596c3653966d0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -620,7 +620,7 @@ void DwarfCompileUnit::constructScopeDIE(LexicalScope *Scope,
void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE,
SmallVector<RangeSpan, 2> Range) {
- HasRangeLists = true;
+ setHasRangeLists(true);
// Add the range list to the set of ranges to be emitted.
auto IndexAndList =
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index fefd8adb3c932..3ca81cad6d76b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -43,7 +44,8 @@ class MDNode;
enum class UnitKind { Skeleton, Full };
class DwarfCompileUnit final : public DwarfUnit {
- bool HasRangeLists = false;
+ bool getHasRangeLists() const { return CURanges.getFlag(0); }
+ void setHasRangeLists(bool Value) { CURanges.setFlag(0, Value); }
/// The start of the unit line section, this is also
/// reused in appyStmtList.
@@ -62,7 +64,7 @@ class DwarfCompileUnit final : public DwarfUnit {
StringMap<const DIE *> GlobalTypes;
// List of ranges for a given compile unit.
- SmallVector<RangeSpan, 2> CURanges;
+ llvm::SmallVectorWithFlags<RangeSpan, 2> CURanges;
// The base address of this unit, if any. Used for relative references in
// ranges/locs.
@@ -190,7 +192,7 @@ class DwarfCompileUnit final : public DwarfUnit {
DwarfDebug *DW, DwarfFile *DWU,
UnitKind Kind = UnitKind::Full);
- bool hasRangeLists() const { return HasRangeLists; }
+ bool hasRangeLists() const { return getHasRangeLists(); }
DwarfCompileUnit *getSkeleton() const {
return Skeleton;
@@ -441,8 +443,12 @@ class DwarfCompileUnit final : public DwarfUnit {
void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie);
/// getRanges - Get the list of ranges for this unit.
- const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; }
- SmallVector<RangeSpan, 2> takeRanges() { return std::move(CURanges); }
+ const SmallVectorWithFlagsImpl<RangeSpan> &getRanges() const {
+ return CURanges;
+ }
+ SmallVector<RangeSpan, 2> takeRanges() {
+ return SmallVector<RangeSpan, 2>(std::move(CURanges));
+ }
void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; }
const MCSymbol *getBaseAddress() const { return BaseAddress; }
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 12fb2829e1ed6..707e2edb4d5f3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -336,9 +336,11 @@ static AccelTableKind computeAccelTableKind(unsigned DwarfVersion,
}
DwarfDebug::DwarfDebug(AsmPrinter *A)
- : DebugHandlerBase(A), DebugLocs(A->OutStreamer->isVerboseAsm()),
+ : DebugHandlerBase(A),
+ ConcreteEntities(decltype(this->ConcreteEntities)::withFlags(
+ (unsigned(bool(A->TM.getTargetTriple().isOSDarwin())) << 1))),
+ DebugLocs(A->OutStreamer->isVerboseAsm()),
SkeletonHolder(A, "skel_string", DIEValueAllocator),
- IsDarwin(A->TM.getTargetTriple().isOSDarwin()),
InfoHolder(A, "info_string", DIEValueAllocator) {
const Triple &TT = Asm->TM.getTargetTriple();
@@ -346,7 +348,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
// precedence; fall back to triple-based defaults.
if (Asm->TM.Options.DebuggerTuning != DebuggerKind::Default)
DebuggerTuning = Asm->TM.Options.DebuggerTuning;
- else if (IsDarwin)
+ else if (getIsDarwin())
DebuggerTuning = DebuggerKind::LLDB;
else if (TT.isPS())
DebuggerTuning = DebuggerKind::SCE;
@@ -363,10 +365,10 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
// Always emit .debug_aranges for SCE tuning.
UseARangesSection = GenerateARangeSection || tuneForSCE();
- HasAppleExtensionAttributes = tuneForLLDB();
+ setHasAppleExtensionAttributes(tuneForLLDB());
// Handle split DWARF.
- HasSplitDwarf = !Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
+ setHasSplitDwarf(!Asm->TM.Options.MCOptions.SplitDwarfFile.empty());
// SCE defaults to linkage names only for abstract subprograms.
if (DwarfLinkageNames == DefaultLinkageNames)
@@ -422,11 +424,11 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
// from each compile and type unit each preceded by a header. The string
// offsets table used by the pre-DWARF v5 split-DWARF implementation uses
// a monolithic string offsets table without any header.
- UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
+ setUseSegmentedStringOffsetsTable(DwarfVersion >= 5);
// 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.shouldEmitDebugEntryValues();
+ setEmitDebugEntryValues(Asm->TM.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.
@@ -1234,7 +1236,7 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
// To avoid the compilation directory being ambiguous, let the line table
// explicitly describe the directory of all files, never relying on the
// compilation directory.
- if (!Asm->OutStreamer->hasRawTextSupport() || SingleCU)
+ if (!Asm->OutStreamer->hasRawTextSupport() || getSingleCU())
Asm->OutStreamer->emitDwarfFile0Directive(
CompilationDir, DIUnit->getFilename(), getMD5AsBytes(DIUnit->getFile()),
DIUnit->getSource(), NewCU.getUniqueID());
@@ -1294,7 +1296,7 @@ void DwarfDebug::beginModule(Module *M) {
return;
assert(NumDebugCUs > 0 && "Asm unexpectedly initialized");
- SingleCU = NumDebugCUs == 1;
+ setSingleCU(NumDebugCUs == 1);
// Create the symbol that designates the start of the unit's contribution
// to the string offsets table. In a split DWARF scenario, only the skeleton
@@ -2924,7 +2926,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
// is still needed as we need its source location.
if (!TheCU.getCUNode()->getDebugInfoForProfiling() &&
TheCU.getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly &&
- LScopes.getAbstractScopesList().empty() && !IsDarwin) {
+ LScopes.getAbstractScopesList().empty() && !getIsDarwin()) {
for (const auto &R : Asm->MBBSectionRanges)
addArangeLabel(SymbolCU(&TheCU, R.second.BeginLabel));
@@ -4195,7 +4197,9 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
NewTU.setType(NewTU.createTypeDIE(CTy));
if (TopLevelType) {
- auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
+ auto TypeUnitsToAdd = SmallVector<
+ std::pair<std::unique_ptr<DwarfTypeUnit>, const DICompositeType *>, 1>(
+ std::move(TypeUnitsUnderConstruction));
TypeUnitsUnderConstruction.clear();
// Types referencing entries in the address table cannot be placed in type
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index eb5ebd85d1b9e..9e90db716bdfd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -366,7 +367,8 @@ class DwarfDebug : public DebugHandlerBase {
DenseMap<const MCSymbol *, uint64_t> SymSize;
/// Collection of abstract variables/labels.
- SmallVector<std::unique_ptr<DbgEntity>, 64> ConcreteEntities;
+ llvm::SmallVectorWithFlags<std::unique_ptr<DbgEntity>, 64, 2>
+ ConcreteEntities;
/// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
/// can refer to them in spite of insertions into this list.
@@ -404,8 +406,8 @@ class DwarfDebug : public DebugHandlerBase {
DenseMap<const MCSection *, const MCSymbol *> SectionLabels;
- SmallVector<
- std::pair<std::unique_ptr<DwarfTypeUnit>, const DICompositeType *>, 1>
+ llvm::SmallVectorWithFlags<
+ std::pair<std::unique_ptr<DwarfTypeUnit>, const DICompositeType *>, 1, 4>
TypeUnitsUnderConstruction;
/// Symbol pointing to the current function's DWARF line table entries.
@@ -472,19 +474,39 @@ class DwarfDebug : public DebugHandlerBase {
/// DWARF5 Experimental Options
/// @{
AccelTableKind TheAccelTableKind;
- bool HasAppleExtensionAttributes;
- bool HasSplitDwarf;
+ bool getHasAppleExtensionAttributes() const {
+ return TypeUnitsUnderConstruction.getFlag(0);
+ }
+ void setHasAppleExtensionAttributes(bool Value) {
+ TypeUnitsUnderConstruction.setFlag(0, Value);
+ }
+ bool getHasSplitDwarf() const {
+ return TypeUnitsUnderConstruction.getFlag(1);
+ }
+ void setHasSplitDwarf(bool Value) {
+ TypeUnitsUnderConstruction.setFlag(1, Value);
+ }
/// Whether to generate the DWARF v5 string offsets table.
/// It consists of a series of contributions, each preceded by a header.
/// The pre-DWARF v5 string offsets table for split dwarf is, in contrast,
/// a monolithic sequence of string offsets.
- bool UseSegmentedStringOffsetsTable;
+ bool getUseSegmentedStringOffsetsTable() const {
+ return TypeUnitsUnderConstruction.getFlag(2);
+ }
+ void setUseSegmentedStringOffsetsTable(bool Value) {
+ TypeUnitsUnderConstruction.setFlag(2, Value);
+ }
/// Enable production of call site parameters needed to print the debug entry
/// values. Useful for testing purposes when a debugger does not support the
/// feature yet.
- bool EmitDebugEntryValues;
+ bool getEmitDebugEntryValues() const {
+ return TypeUnitsUnderConstruction.getFlag(3);
+ }
+ void setEmitDebugEntryValues(bool Value) {
+ TypeUnitsUnderConstruction.setFlag(3, Value);
+ }
/// Separated Dwarf Variables
/// In general these will all be for bits that are left in the
@@ -503,8 +525,10 @@ class DwarfDebug : public DebugHandlerBase {
/// @}
/// True iff there are multiple CUs in this module.
- bool SingleCU;
- bool IsDarwin;
+ bool getSingleCU() const { return ConcreteEntities.getFlag(0); }
+ void setSingleCU(bool Value) { ConcreteEntities.setFlag(0, Value); }
+ bool getIsDarwin() const { return ConcreteEntities.getFlag(1); }
+ void setIsDarwin(bool Value) { ConcreteEntities.setFlag(1, Value); }
AddressPool AddrPool;
@@ -865,11 +889,11 @@ class DwarfDebug : public DebugHandlerBase {
void setTheAccelTableKind(AccelTableKind K) { TheAccelTableKind = K; };
bool useAppleExtensionAttributes() const {
- return HasAppleExtensionAttributes;
+ return getHasAppleExtensionAttributes();
}
/// Returns whether or not to change the current debug info for split DWARF.
- bool useSplitDwarf() const { return HasSplitDwarf; }
+ bool useSplitDwarf() const { return getHasSplitDwarf(); }
/// Returns whether to generate a string offsets table with (possibly shared)
/// contributions from each CU and type unit. This implies the use of
@@ -878,12 +902,10 @@ class DwarfDebug : public DebugHandlerBase {
/// a pre-DWARF v5 implementation of split DWARF sections, which uses a
/// monolithic string offsets table.
bool useSegmentedStringOffsetsTable() const {
- return UseSegmentedStringOffsetsTable;
+ return getUseSegmentedStringOffsetsTable();
}
- bool emitDebugEntryValues() const {
- return EmitDebugEntryValues;
- }
+ bool emitDebugEntryValues() const { return getEmitDebugEntryValues(); }
bool useOpConvert() const {
return EnableOpConvert;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index bfcc1bd5f37dd..5d776d11dee44 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -328,8 +328,9 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
// covering a composite location description. In the future we may want to
// emit entry value operations for each register location in the composite
// location, but until that is supported do not emit anything.
- if ((HasComplexExpression || IsEmittingEntryValue) && DwarfRegs.size() > 1) {
- if (IsEmittingEntryValue)
+ if ((HasComplexExpression || getIsEmittingEntryValue()) &&
+ DwarfRegs.size() > 1) {
+ if (getIsEmittingEntryValue())
cancelEntryValue();
DwarfRegs.clear();
LocationKind = Unknown;
@@ -468,19 +469,19 @@ void DwarfExpression::beginEntryValueExpression(
auto Op = ExprCursor.take();
(void)Op;
assert(Op && isa<DIExpression::EntryValueOp>(*Op));
- assert(!IsEmittingEntryValue && "Already emitting entry value?");
+ assert(!getIsEmittingEntryValue() && "Already emitting entry value?");
assert(cast<DIExpression::EntryValueOp>(*Op).getNumOperations() == 1 &&
"Can currently only emit entry values covering a single operation");
SavedLocationKind = LocationKind;
LocationKind = Register;
LocationFlags |= EntryValue;
- IsEmittingEntryValue = true;
+ setIsEmittingEntryValue(true);
enableTemporaryBuffer();
}
void DwarfExpression::finalizeEntryValue() {
- assert(IsEmittingEntryValue && "Entry value not open?");
+ assert(getIsEmittingEntryValue() && "Entry value not open?");
disableTemporaryBuffer();
emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
@@ -494,11 +495,11 @@ void DwarfExpression::finalizeEntryValue() {
LocationFlags &= ~EntryValue;
LocationKind = SavedLocationKind;
- IsEmittingEntryValue = false;
+ setIsEmittingEntryValue(false);
}
void DwarfExpression::cancelEntryValue() {
- assert(IsEmittingEntryValue && "Entry value not open?");
+ assert(getIsEmittingEntryValue() && "Entry value not open?");
disableTemporaryBuffer();
// The temporary buffer can't be emptied, so for now just assert that nothing
@@ -507,7 +508,7 @@ void DwarfExpression::cancelEntryValue() {
"Began emitting entry value block before cancelling entry value");
LocationKind = SavedLocationKind;
- IsEmittingEntryValue = false;
+ setIsEmittingEntryValue(false);
}
unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize,
@@ -554,7 +555,8 @@ bool DwarfExpression::addExpression(
llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
// Entry values can currently only cover the initial register location,
// and not any other parts of the following DWARF expression.
- assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
+ assert(!getIsEmittingEntryValue() &&
+ "Can't emit entry value around expression");
std::optional<DIExpression::ConvertOp> PrevConvertOp;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 58784df57fd8c..965fce7b210eb 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -16,6 +16,7 @@
#include "ByteStreamer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include <cassert>
#include <cstdint>
@@ -64,12 +65,13 @@ class DwarfExpression {
};
/// Whether we are currently emitting an entry value operation.
- bool IsEmittingEntryValue = false;
+ bool getIsEmittingEntryValue() const { return DwarfRegs.getFlag(0); }
+ void setIsEmittingEntryValue(bool Value) { DwarfRegs.setFlag(0, Value); }
DwarfCompileUnit &CU;
/// The register location, if any.
- SmallVector<Register, 2> DwarfRegs;
+ llvm::SmallVectorWithFlags<Register, 2> DwarfRegs;
/// Current Fragment Offset in Bits.
uint64_t OffsetInBits = 0;
diff --git a/llvm/lib/CodeGen/CallingConvLower.cpp b/llvm/lib/CodeGen/CallingConvLower.cpp
index 644e9bff8929a..7c87e88652eae 100644
--- a/llvm/lib/CodeGen/CallingConvLower.cpp
+++ b/llvm/lib/CodeGen/CallingConvLower.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetLowering.h"
@@ -22,15 +23,17 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
+#include <memory>
using namespace llvm;
CCState::CCState(CallingConv::ID CC, bool IsVarArg, MachineFunction &MF,
SmallVectorImpl<CCValAssign> &Locs, LLVMContext &Context,
bool NegativeOffsets)
- : CallingConv(CC), IsVarArg(IsVarArg), MF(MF),
- TRI(*MF.getSubtarget().getRegisterInfo()), Locs(Locs), Context(Context),
- NegativeOffsets(NegativeOffsets) {
+ : CallingConv(CC), MF(MF), TRI(*MF.getSubtarget().getRegisterInfo()),
+ Locs(Locs), Context(Context),
+ ByValRegs(decltype(this->ByValRegs)::withFlags(
+ unsigned(IsVarArg) | (unsigned(NegativeOffsets) << 2))) {
// No stack is used.
StackSize = 0;
@@ -81,9 +84,8 @@ bool CCState::IsShadowAllocatedReg(MCRegister Reg) const {
/// Analyze an array of argument values,
/// incorporating info about the formals into this state.
-void
-CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
- CCAssignFn Fn) {
+void CCState::AnalyzeFormalArguments(llvm::ArrayRef<ISD::InputArg> Ins,
+ CCAssignFn Fn) {
unsigned NumArgs = Ins.size();
for (unsigned i = 0; i != NumArgs; ++i) {
@@ -96,8 +98,7 @@ CCState::AnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
/// Analyze the return values of a function, returning true if the return can
/// be performed without sret-demotion and false otherwise.
-bool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
- CCAssignFn Fn) {
+bool CCState::CheckReturn(llvm::ArrayRef<ISD::OutputArg> Outs, CCAssignFn Fn) {
// Determine which register each value should be copied into.
for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
MVT VT = Outs[i].VT;
@@ -110,7 +111,7 @@ bool CCState::CheckReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
/// Analyze the returned values of a return,
/// incorporating info about the result values into this state.
-void CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
+void CCState::AnalyzeReturn(llvm::ArrayRef<ISD::OutputArg> Outs,
CCAssignFn Fn) {
// Determine which register each value should be copied into.
for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
@@ -123,7 +124,7 @@ void CCState::AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
/// Analyze the outgoing arguments to a call,
/// incorporating info about the passed values into this state.
-void CCState::AnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
+void CCState::AnalyzeCallOperands(llvm::ArrayRef<ISD::OutputArg> Outs,
CCAssignFn Fn) {
unsigned NumOps = Outs.size();
for (unsigned i = 0; i != NumOps; ++i) {
@@ -161,7 +162,7 @@ void CCState::AnalyzeCallOperands(SmallVectorImpl<MVT> &ArgVTs,
/// Analyze the return values of a call, incorporating info about the passed
/// values into this state.
-void CCState::AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
+void CCState::AnalyzeCallResult(llvm::ArrayRef<ISD::InputArg> Ins,
CCAssignFn Fn) {
for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
MVT VT = Ins[i].VT;
@@ -188,7 +189,7 @@ void CCState::AnalyzeCallResult(MVT VT, Type *OrigTy, CCAssignFn Fn) {
}
void CCState::ensureMaxAlignment(Align Alignment) {
- if (!AnalyzingMustTailForwardedRegs)
+ if (!getAnalyzingMustTailForwardedRegs())
MF.getFrameInfo().ensureMaxAlignment(Alignment);
}
@@ -246,8 +247,21 @@ void CCState::analyzeMustTailForwardedRegisters(
// Oftentimes calling conventions will not user register parameters for
// variadic functions, so we need to assume we're not variadic so that we get
// all the registers that might be used in a non-variadic call.
- SaveAndRestore SavedVarArg(IsVarArg, false);
- SaveAndRestore SavedMustTail(AnalyzingMustTailForwardedRegs, true);
+ auto SavedVarArg = [PackedFlagOwner = this] {
+ const bool PackedFlagOld = PackedFlagOwner->getIsVarArg();
+ PackedFlagOwner->setIsVarArg(false);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setIsVarArg(PackedFlagOld);
+ });
+ }();
+ auto SavedMustTail = [PackedFlagOwner = this] {
+ const bool PackedFlagOld =
+ PackedFlagOwner->getAnalyzingMustTailForwardedRegs();
+ PackedFlagOwner->setAnalyzingMustTailForwardedRegs(true);
+ return llvm::scope_exit([PackedFlagOwner, PackedFlagOld] {
+ PackedFlagOwner->setAnalyzingMustTailForwardedRegs(PackedFlagOld);
+ });
+ }();
for (MVT RegVT : RegParmTypes) {
SmallVector<MCRegister, 8> RemainingRegs;
@@ -264,7 +278,7 @@ void CCState::analyzeMustTailForwardedRegisters(
bool CCState::resultsCompatible(CallingConv::ID CalleeCC,
CallingConv::ID CallerCC, MachineFunction &MF,
LLVMContext &C,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ llvm::ArrayRef<ISD::InputArg> Ins,
CCAssignFn CalleeFn, CCAssignFn CallerFn) {
if (CalleeCC == CallerCC)
return true;
diff --git a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
index da02814f642e0..d086e588e36cb 100644
--- a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
+++ b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
@@ -62,6 +62,7 @@
#include "llvm/CodeGen/ComplexDeinterleavingPass.h"
#include "llvm/ADT/AllocatorList.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
@@ -283,7 +284,7 @@ class ComplexDeinterleavingGraph {
DenseMap<Instruction *, CompositeNode *> RootToNode;
/// Topologically sorted root instructions
- SmallVector<Instruction *, 1> OrderedRoots;
+ llvm::SmallVectorWithFlags<Instruction *, 1> OrderedRoots;
/// When examining a basic block for complex deinterleaving, if it is a simple
/// one-block loop, then the only incoming block is 'Incoming' and the
@@ -320,7 +321,8 @@ class ComplexDeinterleavingGraph {
/// Set this flag to true if RealPHI and ImagPHI were reached during reduction
/// detection.
- bool PHIsFound = false;
+ bool getPHIsFound() const { return OrderedRoots.getFlag(0); }
+ void setPHIsFound(bool Value) { OrderedRoots.setFlag(0, Value); }
/// OldToNewPHI maps the original real PHINode to a new, double-sized PHINode.
/// The new PHINode corresponds to a vector of deinterleaved complex numbers.
@@ -1825,7 +1827,7 @@ void ComplexDeinterleavingGraph::identifyReductionNodes() {
RealPHI = ReductionInfo[Real].first;
ImagPHI = ReductionInfo[Imag].first;
- PHIsFound = false;
+ setPHIsFound(false);
auto Node = identifyNode(Real, Imag);
if (!Node) {
std::swap(Real, Imag);
@@ -1836,7 +1838,7 @@ void ComplexDeinterleavingGraph::identifyReductionNodes() {
// If a node is identified and reduction PHINode is used in the chain of
// operations, mark its operation instructions as used to prevent
// re-identification and attach the node to the real part
- if (Node && PHIsFound) {
+ if (Node && getPHIsFound()) {
LLVM_DEBUG(dbgs() << "Identified reduction starting from instructions: "
<< *Real << " / " << *Imag << "\n");
Processed[i] = true;
@@ -1863,9 +1865,9 @@ void ComplexDeinterleavingGraph::identifyReductionNodes() {
RealPHI = ReductionInfo[Real].first;
ImagPHI = nullptr;
- PHIsFound = false;
+ setPHIsFound(false);
auto Node = identifyNode(Real->getOperand(0), Real->getOperand(1));
- if (Node && PHIsFound) {
+ if (Node && getPHIsFound()) {
LLVM_DEBUG(
dbgs() << "Identified single reduction starting from instruction: "
<< *Real << "/" << *ReductionInfo[Real].second << "\n");
@@ -2244,7 +2246,7 @@ ComplexDeinterleavingGraph::identifyPHINode(Instruction *Real,
if (Real != RealPHI || (ImagPHI && Imag != ImagPHI))
return nullptr;
- PHIsFound = true;
+ setPHIsFound(true);
CompositeNode *PlaceholderNode = prepareCompositeNode(
ComplexDeinterleavingOperation::ReductionPHI, Real, Imag);
return submitCompositeNode(PlaceholderNode);
diff --git a/llvm/lib/CodeGen/DFAPacketizer.cpp b/llvm/lib/CodeGen/DFAPacketizer.cpp
index edbd380eb827b..28b842150d301 100644
--- a/llvm/lib/CodeGen/DFAPacketizer.cpp
+++ b/llvm/lib/CodeGen/DFAPacketizer.cpp
@@ -99,7 +99,7 @@ DefaultVLIWScheduler::DefaultVLIWScheduler(MachineFunction &MF,
MachineLoopInfo &MLI,
AAResults *AA)
: ScheduleDAGInstrs(MF, &MLI), AA(AA) {
- CanHandleTerminators = true;
+ setCanHandleTerminators(true);
}
/// Apply each ScheduleDAGMutation step in order.
diff --git a/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp b/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
index 8d2f9bfb6c5cb..cf64d5dc82a5b 100644
--- a/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
+++ b/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
@@ -22,6 +22,7 @@
#include "llvm/CodeGen/FixupStatepointCallerSaved.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -318,13 +319,14 @@ class StatepointState {
const uint32_t *Mask;
// Cache of frame indexes used on previous instruction processing.
FrameIndexesCache &CacheFI;
- bool AllowGCPtrInCSR;
+ bool getAllowGCPtrInCSR() const { return RegsToReload.getFlag(0); }
+ void setAllowGCPtrInCSR(bool Value) { RegsToReload.setFlag(0, Value); }
// 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;
+ llvm::SmallVectorWithFlags<Register, 8> RegsToReload;
// Map Register to Frame Slot index.
DenseMap<Register, int> RegToSlotIdx;
@@ -333,7 +335,9 @@ class StatepointState {
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) {
+ Mask(Mask), CacheFI(CacheFI),
+ RegsToReload(decltype(this->RegsToReload)::withFlags(
+ unsigned(AllowGCPtrInCSR))) {
// Find statepoint's landing pad, if any.
EHPad = nullptr;
@@ -383,7 +387,7 @@ class StatepointState {
Register Reg = MO.getReg();
assert(Reg.isPhysical() && "Only physical regs are expected");
- if (isCalleeSaved(Reg) && (AllowGCPtrInCSR || !GCRegs.contains(Reg)))
+ if (isCalleeSaved(Reg) && (getAllowGCPtrInCSR() || !GCRegs.contains(Reg)))
continue;
LLVM_DEBUG(dbgs() << "Will spill " << printReg(Reg, &TRI) << " at index "
@@ -484,13 +488,13 @@ class StatepointState {
// We skipped undef uses and did not spill them, so we should not
// proceed with defs here.
if (MI.getOperand(MI.findTiedOperandIdx(I)).isUndef()) {
- if (AllowGCPtrInCSR) {
+ if (getAllowGCPtrInCSR()) {
NewIndices.push_back(NewMI->getNumOperands());
MIB.addReg(Reg, RegState::Define);
}
continue;
}
- if (!AllowGCPtrInCSR) {
+ if (!getAllowGCPtrInCSR()) {
assert(is_contained(RegsToSpill, Reg));
RegsToReload.push_back(Reg);
} else {
@@ -522,7 +526,7 @@ class StatepointState {
} else {
MIB.add(MO);
unsigned OldDef;
- if (AllowGCPtrInCSR && MI.isRegTiedToDefOperand(I, &OldDef)) {
+ if (getAllowGCPtrInCSR() && MI.isRegTiedToDefOperand(I, &OldDef)) {
assert(OldDef < NumDefs);
assert(NewIndices[OldDef] < NumOps);
MIB->tieOperands(NewIndices[OldDef], MIB->getNumOperands() - 1);
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index 02181d9e7d8cd..1d278668f6e16 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -149,8 +149,8 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &CB,
getReturnInfo(CallConv, RetTy, CB.getAttributes(), SplitArgs, DL);
Info.CanLowerReturn = canLowerReturn(MF, CallConv, SplitArgs, IsVarArg);
- Info.IsConvergent = CB.isConvergent();
- Info.NoMerge = CB.hasFnAttr(Attribute::NoMerge);
+ Info.setIsConvergent(CB.isConvergent());
+ Info.setNoMerge(CB.hasFnAttr(Attribute::NoMerge));
if (!Info.CanLowerReturn) {
// Callee requires sret demotion.
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index ebf2eb79a6452..abcea561aee50 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
@@ -190,7 +191,8 @@ class IRTranslatorImpl {
// List of stubbed PHI instructions, for values and basic blocks to be filled
// in once all MachineBasicBlocks have been created.
- SmallVector<std::pair<const PHINode *, SmallVector<MachineInstr *, 1>>, 4>
+ llvm::SmallVectorWithFlags<
+ std::pair<const PHINode *, SmallVector<MachineInstr *, 1>>, 4, 2>
PendingPHIs;
/// Record of what frame index has been allocated to specified allocas for
@@ -681,11 +683,16 @@ class IRTranslatorImpl {
// True when either the Target Machine specifies no optimizations or the
// function has the optnone attribute.
- bool EnableOpts = false;
+ bool getEnableOpts() const { return PendingPHIs.getFlag(0); }
+ void setEnableOpts(bool Value) { PendingPHIs.setFlag(0, Value); }
/// True when the block contains a tail call. This allows the IRTranslator to
/// stop translating such blocks early.
- bool HasTailCall = false;
+ bool getHasTailCall() const { return PendingPHIs.getFlag(1); }
+ bool setHasTailCall(bool Value) {
+ PendingPHIs.setFlag(1, Value);
+ return Value;
+ }
StackProtectorDescriptor SPDescriptor;
@@ -1895,13 +1902,13 @@ void IRTranslatorImpl::emitBitTestHeader(SwitchCG::BitTestBlock &B,
MachineBasicBlock *MBB = B.Cases[0].ThisBB;
- if (!B.FallthroughUnreachable)
+ if (!B.getFallthroughUnreachable())
addSuccessorWithProb(SwitchBB, B.Default, B.DefaultProb);
addSuccessorWithProb(SwitchBB, MBB, B.Prob);
SwitchBB->normalizeSuccProbs();
- if (!B.FallthroughUnreachable) {
+ if (!B.getFallthroughUnreachable()) {
// Conditional branch to the default block.
auto RangeCst = MIB.buildConstant(SwitchOpTy, B.Range);
auto RangeCmp = MIB.buildICmp(CmpInst::Predicate::ICMP_UGT, LLT::integer(1),
@@ -1997,18 +2004,18 @@ bool IRTranslatorImpl::lowerBitTestWorkItem(
// 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) {
+ if (!BTB->getContiguousRange()) {
BTB->Prob += DefaultProb / 2;
BTB->DefaultProb -= DefaultProb / 2;
}
if (FallthroughUnreachable)
- BTB->FallthroughUnreachable = true;
+ BTB->setFallthroughUnreachable(true);
// If we're in the right place, emit the bit test header right now.
if (CurMBB == SwitchMBB) {
emitBitTestHeader(*BTB, SwitchMBB);
- BTB->Emitted = true;
+ BTB->setEmitted(true);
}
return true;
}
@@ -2025,7 +2032,7 @@ bool IRTranslatorImpl::lowerSwitchWorkItem(SwitchCG::SwitchWorkListItem W,
if (++BBI != FuncInfo.MF->end())
NextMBB = &*BBI;
- if (EnableOpts) {
+ if (getEnableOpts()) {
// Here, we order cases by probability so the most likely case will be
// checked first. However, two clusters can have the same probability in
// which case their relative ordering is non-deterministic. So we use Low
@@ -2635,7 +2642,7 @@ bool IRTranslatorImpl::translateTrap(const CallInst &CI,
Info.Callee = MachineOperand::CreateES(TrapFuncName.data());
Info.CB = &CI;
Info.OrigRet = {Register(), Type::getVoidTy(CI.getContext()), 0};
- Info.NoMerge = CI.cannotMerge();
+ Info.setNoMerge(CI.cannotMerge());
return CLI->lowerCall(MIRBuilder, Info);
}
@@ -3602,9 +3609,9 @@ bool IRTranslatorImpl::translateCallBase(const CallBase &CB,
// Check if we just inserted a tail call.
if (Success) {
- assert(!HasTailCall && "Can't tail call return twice from block?");
+ assert(!getHasTailCall() && "Can't tail call return twice from block?");
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
- HasTailCall = TII->isTailCall(*std::prev(MIRBuilder.getInsertPt()));
+ setHasTailCall(TII->isTailCall(*std::prev(MIRBuilder.getInsertPt())));
}
return Success;
@@ -4845,7 +4852,7 @@ bool IRTranslatorImpl::finalizeBasicBlock(const BasicBlock &BB,
MachineBasicBlock &MBB) {
for (auto &BTB : SL->BitTestCases) {
// Emit header first, if it wasn't already emitted.
- if (!BTB.Emitted)
+ if (!BTB.getEmitted())
emitBitTestHeader(BTB, BTB.Parent);
BranchProbability UnhandledProb = BTB.Prob;
@@ -4862,7 +4869,8 @@ bool IRTranslatorImpl::finalizeBasicBlock(const BasicBlock &BB,
// test, and delete the last bit test.
MachineBasicBlock *NextMBB;
- if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
+ if ((BTB.getContiguousRange() || BTB.getFallthroughUnreachable()) &&
+ 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;
@@ -4876,7 +4884,8 @@ bool IRTranslatorImpl::finalizeBasicBlock(const BasicBlock &BB,
emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j], MBB);
- if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
+ if ((BTB.getContiguousRange() || BTB.getFallthroughUnreachable()) &&
+ j + 2 == ej) {
// We need to record the replacement phi edge here that normally
// happens in emitBitTestCase before we delete the case, otherwise the
// phi edge will be lost.
@@ -4893,7 +4902,7 @@ bool IRTranslatorImpl::finalizeBasicBlock(const BasicBlock &BB,
CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
BTB.Default->getBasicBlock()};
addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
- if (!BTB.ContiguousRange) {
+ if (!BTB.getContiguousRange()) {
addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
}
}
@@ -5150,13 +5159,13 @@ bool IRTranslatorImpl::runOnMachineFunction(
MRI = &MF->getRegInfo();
DL = &F.getDataLayout();
const TargetMachine &TM = MF->getTarget();
- EnableOpts = OptLevel != CodeGenOptLevel::None && !ShouldSkipOpts;
+ setEnableOpts(OptLevel != CodeGenOptLevel::None && !ShouldSkipOpts);
FuncInfo.MF = MF;
// Prefer the "exception-model" module flag, else the TargetOptions default.
FuncInfo.ExceptionModel = F.getParent()->getExceptionModel();
if (FuncInfo.ExceptionModel == ExceptionHandling::Default)
FuncInfo.ExceptionModel = TM.getExceptionModel();
- if (EnableOpts) {
+ if (getEnableOpts()) {
AA = GetAAResults();
FuncInfo.BPI = GetBPI();
AC = GetAC();
@@ -5273,14 +5282,14 @@ bool IRTranslatorImpl::runOnMachineFunction(
// Set the insertion point of all the following translations to
// the end of this basic block.
CurBuilder->setMBB(MBB);
- HasTailCall = false;
+ setHasTailCall(false);
for (const Instruction &Inst : *BB) {
// If we translated a tail call in the last step, then we know
// everything after the call is either a return, or something that is
// handled by the call itself. (E.g. a lifetime marker or assume
// intrinsic.) In this case, we should stop translating the block and
// move on.
- if (HasTailCall)
+ if (getHasTailCall())
break;
#ifndef NDEBUG
Verifier.setCurrentInst(&Inst);
diff --git a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
index bac2f52c9ede0..9f8c0272d6da9 100644
--- a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
@@ -344,12 +345,14 @@ class RegBankSelectImpl {
/// Index of the operand that will be repaired.
unsigned OpIdx;
/// Are all the insert points materializeable?
- bool CanMaterialize;
+ bool getCanMaterialize() const { return InsertPoints.getFlag(0); }
+ void setCanMaterialize(bool Value) { InsertPoints.setFlag(0, Value); }
/// Is there any of the insert points needing splitting?
- bool HasSplit = false;
+ bool getHasSplit() const { return InsertPoints.getFlag(1); }
+ void setHasSplit(bool Value) { InsertPoints.setFlag(1, Value); }
/// Insertion point for the repair code.
/// The repairing code needs to happen just before these points.
- InsertionPoints InsertPoints;
+ llvm::SmallVectorWithFlagsFor<InsertionPoints, 2> InsertPoints;
/// Some insertion points may need to update the liveness and such.
Pass *P;
MachineFunctionAnalysisManager *MFAM;
@@ -369,8 +372,8 @@ class RegBankSelectImpl {
/// @{
RepairingKind getKind() const { return Kind; }
unsigned getOpIdx() const { return OpIdx; }
- bool canMaterialize() const { return CanMaterialize; }
- bool hasSplit() { return HasSplit; }
+ bool canMaterialize() const { return getCanMaterialize(); }
+ bool hasSplit() { return getHasSplit(); }
/// @}
/// \name Overloaded methods to add an insertion point.
@@ -408,8 +411,8 @@ class RegBankSelectImpl {
assert(NewKind != Kind && "Already of the right Kind");
Kind = NewKind;
InsertPoints.clear();
- CanMaterialize = NewKind != RepairingKind::Impossible;
- HasSplit = false;
+ setCanMaterialize(NewKind != RepairingKind::Impossible);
+ setHasSplit(false);
assert(NewKind != RepairingKind::Insert &&
"We would need more MI to switch to Insert");
}
@@ -1400,7 +1403,9 @@ RegBankSelectImpl::RepairingPlacement::RepairingPlacement(
RepairingPlacement::RepairingKind Kind)
// Default is, we are going to insert code to repair OpIdx.
: Kind(Kind), OpIdx(OpIdx),
- CanMaterialize(Kind != RepairingKind::Impossible), P(P) {
+ InsertPoints(decltype(this->InsertPoints)::withFlags(
+ unsigned(bool(Kind != RepairingKind::Impossible)))),
+ P(P) {
const MachineOperand &MO = MI.getOperand(OpIdx);
assert(MO.isReg() && "Trying to repair a non-reg operand");
@@ -1506,8 +1511,14 @@ void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
void RegBankSelectImpl::RepairingPlacement::addInsertPoint(
RegBankSelectImpl::InsertPoint &Point) {
- CanMaterialize &= Point.canMaterialize();
- HasSplit |= Point.isSplit();
+ [&] {
+ auto PackedFlagValue = Point.canMaterialize();
+ return setCanMaterialize(getCanMaterialize() & PackedFlagValue);
+ }();
+ [&] {
+ auto PackedFlagValue = Point.isSplit();
+ return setHasSplit(getHasSplit() | PackedFlagValue);
+ }();
InsertPoints.emplace_back(&Point);
}
diff --git a/llvm/lib/CodeGen/LexicalScopes.cpp b/llvm/lib/CodeGen/LexicalScopes.cpp
index 9fc9ac9a66d41..e7ecf8759043a 100644
--- a/llvm/lib/CodeGen/LexicalScopes.cpp
+++ b/llvm/lib/CodeGen/LexicalScopes.cpp
@@ -257,7 +257,7 @@ void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
auto &ScopePosition = WorkStack.back();
LexicalScope *WS = ScopePosition.first;
size_t ChildNum = ScopePosition.second++;
- const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
+ ArrayRef<LexicalScope *> Children = WS->getChildren();
if (ChildNum < Children.size()) {
auto &ChildScope = Children[ChildNum];
WorkStack.push_back(std::make_pair(ChildScope, 0));
@@ -349,7 +349,7 @@ LLVM_DUMP_METHOD void LexicalScope::dump(unsigned Indent) const {
const MDNode *N = Desc;
err.indent(Indent);
N->dump();
- if (AbstractScope)
+ if (isAbstractScope())
err << std::string(Indent, ' ') << "Abstract Scope\n";
if (!Children.empty())
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index e34b5e4edaea9..077d1e07e3101 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -84,6 +84,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -192,7 +193,8 @@ class TransferTracker {
MLocTracker *MTracker;
MachineFunction &MF;
const DebugVariableMap &DVMap;
- bool ShouldEmitDebugEntryValues;
+ bool getShouldEmitDebugEntryValues() const { return VarLocs.getFlag(0); }
+ void setShouldEmitDebugEntryValues(bool Value) { VarLocs.setFlag(0, Value); }
/// Record of all changes in variable locations at a block position. Awkwardly
/// we allow inserting either before or after the point: MBB != nullptr
@@ -233,7 +235,7 @@ class TransferTracker {
/// between TransferTrackers view of variable locations and MLocTrackers. For
/// example, MLocTracker observes all clobbers, but TransferTracker lazily
/// does not.
- SmallVector<ValueIDNum, 32> VarLocs;
+ llvm::SmallVectorWithFlags<ValueIDNum, 32> VarLocs;
/// Map from LocIdxes to which DebugVariables are based that location.
/// Mantained while stepping through the block. Not accurate if
@@ -283,7 +285,7 @@ class TransferTracker {
: TII(TII), MTracker(MTracker), MF(MF), DVMap(DVMap), TRI(TRI),
CalleeSavedRegs(CalleeSavedRegs) {
TLI = MF.getSubtarget().getTargetLowering();
- this->ShouldEmitDebugEntryValues = ShouldEmitDebugEntryValues;
+ this->setShouldEmitDebugEntryValues(ShouldEmitDebugEntryValues);
}
bool isCalleeSaved(LocIdx L) const {
@@ -666,7 +668,7 @@ class TransferTracker {
const ValueIDNum &Num) {
// Is this variable location a candidate to be an entry value. First,
// should we be trying this at all?
- if (!ShouldEmitDebugEntryValues)
+ if (!getShouldEmitDebugEntryValues())
return false;
const DIExpression *DIExpr = Prop.DIExpr;
@@ -1902,7 +1904,7 @@ void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) {
// call, etc). If it is a call that modifies SP, recognise the SP register
// defs.
bool CallChangesSP = false;
- if (AdjustsStackInCalls && MI.isCall() && MI.getOperand(0).isSymbol() &&
+ if (getAdjustsStackInCalls() && MI.isCall() && MI.getOperand(0).isSymbol() &&
!strcmp(MI.getOperand(0).getSymbolName(), StackProbeSymbolName.data()))
CallChangesSP = true;
@@ -3541,7 +3543,7 @@ void InstrRefBasedLDV::makeDepthFirstEjectionMap(
LexicalScope *WS = ScopePosition.first;
ssize_t ChildNum = ScopePosition.second--;
- const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
+ ArrayRef<LexicalScope *> Children = WS->getChildren();
if (ChildNum >= 0) {
// If ChildNum is positive, there are remaining children to explore.
// Push the child and its children-count onto the stack.
@@ -3649,7 +3651,7 @@ bool InstrRefBasedLDV::depthFirstVLocAndEmit(
HighestDFSIn = std::max(HighestDFSIn, WS->getDFSIn());
// Descend into any scope nests.
- const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
+ ArrayRef<LexicalScope *> Children = WS->getChildren();
if (ChildNum < (ssize_t)Children.size()) {
// There are children to explore -- push onto stack and continue.
auto &ChildScope = Children[ChildNum];
@@ -3739,9 +3741,10 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
LS.scanFunction(MF);
const auto &STI = MF.getSubtarget();
- AdjustsStackInCalls = MFI->adjustsStack() &&
- STI.getFrameLowering()->stackProbeFunctionModifiesSP();
- if (AdjustsStackInCalls)
+ setAdjustsStackInCalls(
+ MFI->adjustsStack() &&
+ STI.getFrameLowering()->stackProbeFunctionModifiesSP());
+ if (getAdjustsStackInCalls())
StackProbeSymbolName = STI.getTargetLowering()->getStackProbeSymbolName(MF);
MTracker =
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
index d73697fe5b4fc..5f327b9634e7e 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/UniqueVector.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -1222,7 +1223,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// DBG_PHI read and where. Populated and edited during the machine value
/// location problem -- we use LLVMs SSA Updater to fix changes by
/// optimizations that destroy PHI instructions.
- SmallVector<DebugPHIRecord, 32> DebugPHINumToValue;
+ llvm::SmallVectorWithFlags<DebugPHIRecord, 32> DebugPHINumToValue;
// Map of overlapping variable fragments.
OverlapMap OverlapFragments;
@@ -1245,7 +1246,10 @@ class InstrRefBasedLDV : public LDVImpl {
/// True if we need to examine call instructions for stack clobbers. We
/// normally assume that they don't clobber SP, but stack probes on Windows
/// do.
- bool AdjustsStackInCalls = false;
+ bool getAdjustsStackInCalls() const { return DebugPHINumToValue.getFlag(0); }
+ void setAdjustsStackInCalls(bool Value) {
+ DebugPHINumToValue.setFlag(0, Value);
+ }
/// If AdjustsStackInCalls is true, this holds the name of the target's stack
/// probe function, which is the function we expect will alter the stack
diff --git a/llvm/lib/CodeGen/LiveIntervalUnion.cpp b/llvm/lib/CodeGen/LiveIntervalUnion.cpp
index 4f7b7ba5974cc..3c8d0d50c2448 100644
--- a/llvm/lib/CodeGen/LiveIntervalUnion.cpp
+++ b/llvm/lib/CodeGen/LiveIntervalUnion.cpp
@@ -143,16 +143,17 @@ bool LiveIntervalUnion::Query::isSeenInterference(
unsigned
LiveIntervalUnion::Query::collectInterferingVRegs(unsigned MaxInterferingRegs) {
// Fast path return if we already have the desired information.
- if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs)
+ if (getSeenAllInterferences() ||
+ InterferingVRegs.size() >= MaxInterferingRegs)
return InterferingVRegs.size();
// Set up iterators on the first call.
- if (!CheckedFirstInterference) {
- CheckedFirstInterference = true;
+ if (!getCheckedFirstInterference()) {
+ setCheckedFirstInterference(true);
// Quickly skip interference check for empty sets.
if (LR->empty() || LiveUnion->empty()) {
- SeenAllInterferences = true;
+ setSeenAllInterferences(true);
return 0;
}
@@ -179,7 +180,7 @@ LiveIntervalUnion::Query::collectInterferingVRegs(unsigned MaxInterferingRegs) {
}
// This LiveUnion segment is no longer interesting.
if (!(++LiveUnionI).valid()) {
- SeenAllInterferences = true;
+ setSeenAllInterferences(true);
return InterferingVRegs.size();
}
}
@@ -200,7 +201,7 @@ LiveIntervalUnion::Query::collectInterferingVRegs(unsigned MaxInterferingRegs) {
// Still not overlapping. Catch up LiveUnionI.
LiveUnionI.advanceTo(LRI->start);
}
- SeenAllInterferences = true;
+ setSeenAllInterferences(true);
return InterferingVRegs.size();
}
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index 0568890583c1d..34c086184f346 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -54,6 +54,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -125,11 +126,19 @@ std::optional<DestSourcePair> isCopyInstr(const MachineInstr &MI,
class CopyTracker {
struct CopyInfo {
+ CopyInfo() = default;
+ CopyInfo(MachineInstr *MI, bool Avail)
+ : MI(MI), DefRegs(decltype(this->DefRegs)::withFlags(unsigned(Avail))) {
+ }
MachineInstr *MI = nullptr;
MachineInstr *LastSeenUseInCopy = nullptr;
SmallPtrSet<MachineInstr *, 4> SrcUsers;
- SmallVector<MCRegister, 4> DefRegs;
- bool Avail = false;
+ llvm::SmallVectorWithFlags<MCRegister, 4> DefRegs;
+ bool getAvail() const { return DefRegs.getFlag(0); }
+ bool setAvail(bool Value) {
+ DefRegs.setFlag(0, Value);
+ return Value;
+ }
};
DenseMap<MCRegUnit, CopyInfo> Copies;
@@ -167,7 +176,7 @@ class CopyTracker {
for (MCRegUnit Unit : TRI.regunits(Reg)) {
auto CI = Copies.find(Unit);
if (CI != Copies.end())
- CI->second.Avail = false;
+ CI->second.setAvail(false);
}
}
}
@@ -321,7 +330,7 @@ class CopyTracker {
// Remember Dst is defined by the copy.
for (MCRegUnit Unit : TRI.regunits(Dst))
- Copies[Unit] = {MI, nullptr, {}, {}, true};
+ Copies[Unit] = CopyInfo(MI, true);
// Remember source that's copied to Dst. Once it's clobbered, then
// it's no longer available for copy propagation.
@@ -343,7 +352,7 @@ class CopyTracker {
auto CI = Copies.find(RegUnit);
if (CI == Copies.end())
return nullptr;
- if (MustBeAvailable && !CI->second.Avail)
+ if (MustBeAvailable && !CI->second.getAvail())
return nullptr;
return CI->second.MI;
}
@@ -422,7 +431,7 @@ class CopyTracker {
bool UseCopyInstr) {
MCRegUnit RU = *TRI.regunits(Reg).begin();
auto CI = Copies.find(RU);
- if (CI == Copies.end() || !CI->second.Avail)
+ if (CI == Copies.end() || !CI->second.getAvail())
return nullptr;
MachineInstr *DefCopy = CI->second.MI;
@@ -455,7 +464,7 @@ class CopyTracker {
for (MCRegUnit DstUnit : TRI.regunits(DstReg)) {
if (!PreservedRegUnits.test(static_cast<unsigned>(DstUnit))) {
if (auto CI = Copies.find(DstUnit); CI != Copies.end()) {
- CI->second.Avail = false;
+ CI->second.setAvail(false);
}
}
}
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index b0f06907ef9da..8e10ad87d89ac 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -1404,11 +1404,11 @@ bool MachineFunction::shouldUseDebugInstrRef() const {
}
bool MachineFunction::useDebugInstrRef() const {
- return UseDebugInstrRef;
+ return getUseDebugInstrRefFlag();
}
void MachineFunction::setUseDebugInstrRef(bool Use) {
- UseDebugInstrRef = Use;
+ setUseDebugInstrRefFlag(Use);
}
// Use one million as a high / reserved number.
diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index b7b29ba9fb0ad..ae70aab0f830b 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/lib/CodeGen/MachineLICM.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -127,8 +128,10 @@ namespace {
MachineRegisterInfo *MRI = nullptr;
const RegisterClassInfo *RegClassInfo = nullptr;
TargetSchedModel SchedModel;
- bool PreRegAlloc = false;
- bool HasProfileData = false;
+ bool getPreRegAlloc() const { return BackTrace.getFlag(0); }
+ void setPreRegAlloc(bool Value) { BackTrace.setFlag(0, Value); }
+ bool getHasProfileData() const { return BackTrace.getFlag(1); }
+ void setHasProfileData(bool Value) { BackTrace.setFlag(1, Value); }
Pass *LegacyPass;
MachineFunctionAnalysisManager *MFAM;
@@ -139,8 +142,16 @@ namespace {
MachineDomTreeUpdater *MDTU = nullptr; // Wraps current dominator tree
// State that is updated as we process loops
- bool Changed = false; // True if a loop is changed.
- bool FirstInLoop = false; // True if it's the first LICM in the loop.
+ bool getChanged() const { return BackTrace.getFlag(2); }
+ bool setChanged(bool Value) {
+ BackTrace.setFlag(2, Value);
+ return Value;
+ } // True if a loop is changed.
+ bool getFirstInLoop() const { return BackTrace.getFlag(3); }
+ bool setFirstInLoop(bool Value) {
+ BackTrace.setFlag(3, Value);
+ return Value;
+ } // True if it's the first LICM in the loop.
// Holds information about whether it is allowed to move load instructions
// out of the loop
@@ -168,7 +179,7 @@ namespace {
SmallVector<unsigned, 8> RegLimit;
// Register pressure on path leading from loop preheader to current BB.
- SmallVector<SmallVector<unsigned, 8>, 16> BackTrace;
+ llvm::SmallVectorWithFlags<SmallVector<unsigned, 8>, 16, 4> BackTrace;
// For each opcode per preheader, keep a list of potential CSE instructions.
DenseMap<MachineBasicBlock *,
@@ -189,7 +200,9 @@ namespace {
public:
MachineLICMImpl(bool PreRegAlloc, Pass *LegacyPass,
MachineFunctionAnalysisManager *MFAM)
- : PreRegAlloc(PreRegAlloc), LegacyPass(LegacyPass), MFAM(MFAM) {
+ : LegacyPass(LegacyPass), MFAM(MFAM),
+ BackTrace(
+ decltype(this->BackTrace)::withFlags(unsigned(PreRegAlloc))) {
assert((LegacyPass || MFAM) && "LegacyPass or MFAM must be provided");
assert(!(LegacyPass && MFAM) &&
"LegacyPass and MFAM cannot be provided at the same time");
@@ -387,7 +400,7 @@ bool MachineLICMImpl::run(MachineFunction &MF) {
? GET_RESULT(MachineBlockFrequency, getMBFI, Info)
: nullptr;
- Changed = FirstInLoop = false;
+ setChanged(setFirstInLoop(false));
const TargetSubtargetInfo &ST = MF.getSubtarget();
TII = ST.getInstrInfo();
TLI = ST.getTargetLowering();
@@ -396,15 +409,15 @@ bool MachineLICMImpl::run(MachineFunction &MF) {
MRI = &MF.getRegInfo();
SchedModel.init(&ST);
- HasProfileData = MF.getFunction().hasProfileData();
+ setHasProfileData(MF.getFunction().hasProfileData());
- if (PreRegAlloc)
+ if (getPreRegAlloc())
LLVM_DEBUG(dbgs() << "******** Pre-regalloc Machine LICM: ");
else
LLVM_DEBUG(dbgs() << "******** Post-regalloc Machine LICM: ");
LLVM_DEBUG(dbgs() << MF.getName() << " ********\n");
- if (PreRegAlloc) {
+ if (getPreRegAlloc()) {
// Estimate register pressure during pre-regalloc pass.
unsigned NumRPS = TRI->getNumRegPressureSets();
RegPressure.resize(NumRPS);
@@ -421,19 +434,19 @@ bool MachineLICMImpl::run(MachineFunction &MF) {
while (!Worklist.empty()) {
MachineLoop *CurLoop = Worklist.pop_back_val();
- if (!PreRegAlloc) {
+ if (!getPreRegAlloc()) {
HoistRegionPostRA(CurLoop);
} else {
// CSEMap is initialized for loop header when the first instruction is
// being hoisted.
MachineDomTreeNode *N = MDTU->getDomTree().getNode(CurLoop->getHeader());
- FirstInLoop = true;
+ setFirstInLoop(true);
HoistOutOfLoop(N, CurLoop);
CSEMap.clear();
}
}
releaseMemory();
- return Changed;
+ return getChanged();
}
/// Return true if instruction stores to the specified frame.
@@ -763,7 +776,7 @@ void MachineLICMImpl::HoistPostRA(MachineInstr *MI, Register Def,
AddToLiveIns(Def, CurLoop);
++NumPostRAHoisted;
- Changed = true;
+ setChanged(true);
}
/// Check if this mbb is guaranteed to execute. If not then a load from this mbb
@@ -1508,7 +1521,7 @@ MachineInstr *
MachineLICMImpl::LookForDuplicate(const MachineInstr *MI,
std::vector<MachineInstr *> &PrevMIs) {
for (MachineInstr *PrevMI : PrevMIs)
- if (TII->produceSameValue(*MI, *PrevMI, (PreRegAlloc ? MRI : nullptr)))
+ if (TII->produceSameValue(*MI, *PrevMI, (getPreRegAlloc() ? MRI : nullptr)))
return PrevMI;
return nullptr;
@@ -1614,7 +1627,7 @@ unsigned MachineLICMImpl::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader,
// Disable the instruction hoisting due to block hotness
if ((DisableHoistingToHotterBlocks == UseBFI::All ||
- (DisableHoistingToHotterBlocks == UseBFI::PGO && HasProfileData)) &&
+ (DisableHoistingToHotterBlocks == UseBFI::PGO && getHasProfileData())) &&
isTgtHotterThanSrc(SrcBlock, Preheader)) {
++NumNotHoistedDueToHotness;
return HoistResult::NotHoisted;
@@ -1648,9 +1661,9 @@ unsigned MachineLICMImpl::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader,
// If this is the first instruction being hoisted to the preheader,
// initialize the CSE map with potential common expressions.
- if (FirstInLoop) {
+ if (getFirstInLoop()) {
InitCSEMap(Preheader);
- FirstInLoop = false;
+ setFirstInLoop(false);
}
// Look for opportunity to CSE the hoisted instruction.
@@ -1694,7 +1707,7 @@ unsigned MachineLICMImpl::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader,
}
++NumHoisted;
- Changed = true;
+ setChanged(true);
if (HasCSEDone || HasExtractHoistableLoad)
return HoistResult::Hoisted | HoistResult::ErasedMI;
@@ -1714,7 +1727,7 @@ MachineBasicBlock *MachineLICMImpl::getOrCreatePreheader(MachineLoop *CurLoop) {
MachineBasicBlock *NewPreheader =
Pred->SplitCriticalEdge(CurLoop->getHeader(), LegacyPass, MFAM, MDTU);
if (NewPreheader)
- Changed = true;
+ setChanged(true);
return NewPreheader;
}
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index 540c9c8b018da..f0d8509d8a6d8 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -57,6 +57,7 @@
#include "llvm/CodeGen/MachineOutliner.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
@@ -191,13 +192,14 @@ struct InstructionMapper {
/// Stores the location of the instruction associated with the integer
/// at index i in \p UnsignedVec for each index i.
- SmallVector<MachineBasicBlock::iterator> InstrList;
+ llvm::SmallVectorWithFlags<MachineBasicBlock::iterator> InstrList;
// 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;
+ bool getAddedIllegalLastTime() const { return InstrList.getFlag(0); }
+ void setAddedIllegalLastTime(bool Value) { InstrList.setFlag(0, Value); }
/// Maps \p *It to a legal integer.
///
@@ -212,7 +214,7 @@ struct InstructionMapper {
SmallVector<MachineBasicBlock::iterator> &InstrListForMBB) {
// We added something legal, so we should unset the AddedLegalLastTime
// flag.
- AddedIllegalLastTime = false;
+ setAddedIllegalLastTime(false);
// If we have at least two adjacent legal instructions (which may have
// invisible instructions in between), remember that.
@@ -263,11 +265,11 @@ struct InstructionMapper {
CanOutlineWithPrevInstr = false;
// Only add one illegal number per range of legal numbers.
- if (AddedIllegalLastTime)
+ if (getAddedIllegalLastTime())
return IllegalInstrNumber;
// Remember that we added an illegal number last time.
- AddedIllegalLastTime = true;
+ setAddedIllegalLastTime(true);
unsigned MINumber = IllegalInstrNumber;
InstrListForMBB.push_back(It);
@@ -388,7 +390,7 @@ struct InstructionMapper {
// Normally this is set by mapTo(Blah)Unsigned, but we just want to
// skip this instruction. So, unset the flag here.
++NumInvisible;
- AddedIllegalLastTime = false;
+ setAddedIllegalLastTime(false);
break;
}
}
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index be68d42b187a7..9c673a375498c 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -40,6 +40,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -245,7 +246,7 @@ namespace {
/// information related to the instruction.
struct SUnitWithMemInfo {
SUnit *SU;
- SmallVector<const Value *, 2> UnderlyingObjs;
+ llvm::SmallVectorWithFlags<const Value *, 2> UnderlyingObjs;
/// The value of a memory operand.
const Value *MemOpValue = nullptr;
@@ -256,7 +257,8 @@ struct SUnitWithMemInfo {
AAMDNodes AATags;
/// True if all the underlying objects are identified.
- bool IsAllIdentified = false;
+ bool getIsAllIdentified() const { return UnderlyingObjs.getFlag(0); }
+ void setIsAllIdentified(bool Value) { UnderlyingObjs.setFlag(0, Value); }
SUnitWithMemInfo(SUnit *SU);
@@ -1138,7 +1140,7 @@ SUnitWithMemInfo::SUnitWithMemInfo(SUnit *SU) : SU(SU) {
return;
for (const Value *Obj : UnderlyingObjs)
if (!isIdentifiedObject(Obj)) {
- IsAllIdentified = false;
+ setIsAllIdentified(false);
break;
}
}
@@ -1147,7 +1149,7 @@ bool SUnitWithMemInfo::isTriviallyDisjoint(
const SUnitWithMemInfo &Other) const {
// If all underlying objects are identified objects and there is no overlap
// between them, then these two instructions are disjoint.
- if (!IsAllIdentified || !Other.IsAllIdentified)
+ if (!getIsAllIdentified() || !Other.getIsAllIdentified())
return false;
for (const Value *Obj : UnderlyingObjs)
if (llvm::is_contained(Other.UnderlyingObjs, Obj))
@@ -1168,7 +1170,9 @@ bool SUnitWithMemInfo::getUnderlyingObjects() {
return false;
MemOpValue = MM->getValue();
MemOpOffset = MM->getOffset();
- llvm::getUnderlyingObjects(MemOpValue, UnderlyingObjs);
+ SmallVector<const Value *, 2> Objects;
+ llvm::getUnderlyingObjects(MemOpValue, Objects);
+ UnderlyingObjs.assign(std::move(Objects));
// TODO: A no alias scope may be valid only in a single iteration. In this
// case we need to peel off it like LoopAccessAnalysis does.
@@ -3988,7 +3992,7 @@ LLVM_DUMP_METHOD void NodeSet::dump() const { print(dbgs()); }
void ResourceManager::dumpMRT() const {
LLVM_DEBUG({
- if (UseDFA)
+ if (getUseDFA())
return;
std::stringstream SS;
SS << "MRT:\n";
@@ -4011,7 +4015,8 @@ void ResourceManager::dumpMRT() const {
ResourceManager::ResourceManager(const TargetSubtargetInfo *ST,
ScheduleDAGInstrs *DAG)
: STI(ST), SM(ST->getSchedModel()), ST(ST), TII(ST->getInstrInfo()),
- DAG(DAG), UseDFA(ST->useDFAforSMS()),
+ DAG(DAG), NumScheduledMops(decltype(this->NumScheduledMops)::withFlags(
+ unsigned(bool(ST->useDFAforSMS())))),
ProcResourceMasks(SM.getNumProcResourceKinds(), 0),
IssueWidth(SM.IssueWidth) {
initProcResourceVectors(SM, ProcResourceMasks);
@@ -4069,7 +4074,7 @@ bool ResourceManager::canReserveResources(SUnit &SU, int Cycle) {
if (SwpDebugResource)
dbgs() << "canReserveResources:\n";
});
- if (UseDFA)
+ if (getUseDFA())
return DFAResources[positiveModulo(Cycle, InitiationInterval)]
->canReserveResources(&SU.getInstr()->getDesc());
@@ -4095,7 +4100,7 @@ void ResourceManager::reserveResources(SUnit &SU, int Cycle) {
if (SwpDebugResource)
dbgs() << "reserveResources:\n";
});
- if (UseDFA)
+ if (getUseDFA())
return DFAResources[positiveModulo(Cycle, InitiationInterval)]
->reserveResources(&SU.getInstr()->getDesc());
@@ -4120,7 +4125,7 @@ void ResourceManager::reserveResources(SUnit &SU, int Cycle) {
void ResourceManager::reserveResources(const MCSchedClassDesc *SCDesc,
int Cycle) {
- assert(!UseDFA);
+ assert(!getUseDFA());
for (const MCWriteProcResEntry &PRE : make_range(
STI->getWriteProcResBegin(SCDesc), STI->getWriteProcResEnd(SCDesc)))
for (int C = Cycle; C < Cycle + PRE.ReleaseAtCycle; ++C)
@@ -4132,7 +4137,7 @@ void ResourceManager::reserveResources(const MCSchedClassDesc *SCDesc,
void ResourceManager::unreserveResources(const MCSchedClassDesc *SCDesc,
int Cycle) {
- assert(!UseDFA);
+ assert(!getUseDFA());
for (const MCWriteProcResEntry &PRE : make_range(
STI->getWriteProcResBegin(SCDesc), STI->getWriteProcResEnd(SCDesc)))
for (int C = Cycle; C < Cycle + PRE.ReleaseAtCycle; ++C)
@@ -4143,7 +4148,7 @@ void ResourceManager::unreserveResources(const MCSchedClassDesc *SCDesc,
}
bool ResourceManager::isOverbooked() const {
- assert(!UseDFA);
+ assert(!getUseDFA());
for (int Slot = 0; Slot < InitiationInterval; ++Slot) {
for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
const MCProcResourceDesc *Desc = SM.getProcResource(I);
@@ -4157,7 +4162,7 @@ bool ResourceManager::isOverbooked() const {
}
int ResourceManager::calculateResMIIDFA() const {
- assert(UseDFA);
+ assert(getUseDFA());
// Sort the instructions by the number of available choices for scheduling,
// least to most. Use the number of critical resources as the tie breaker.
@@ -4220,7 +4225,7 @@ int ResourceManager::calculateResMIIDFA() const {
}
int ResourceManager::calculateResMII() const {
- if (UseDFA)
+ if (getUseDFA())
return calculateResMIIDFA();
// Count each resource consumption and divide it by the number of units.
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 035ccaac06a5a..6d912b5bb087a 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -42,11 +42,10 @@ static cl::opt<bool> EnableSubRegLiveness("enable-subreg-liveness", cl::Hidden,
// Pin the vtable to this file.
void MachineRegisterInfo::Delegate::anchor() {}
-MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
- : MF(MF),
- TracksSubRegLiveness(EnableSubRegLiveness.getNumOccurrences()
- ? EnableSubRegLiveness
- : MF->getSubtarget().enableSubRegLiveness()) {
+MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF) : MF(MF) {
+ UpdatedCSRs.setFlag(0, EnableSubRegLiveness.getNumOccurrences()
+ ? EnableSubRegLiveness
+ : MF->getSubtarget().enableSubRegLiveness());
unsigned NumRegs = getTargetRegisterInfo()->getNumRegs();
VRegInfo.reserve(256);
UsedPhysRegMask.resize(NumRegs);
@@ -625,7 +624,7 @@ void MachineRegisterInfo::disableCalleeSavedRegister(MCRegister Reg) {
assert(Reg && (Reg < TRI->getNumRegs()) &&
"Trying to disable an invalid register");
- if (!IsUpdatedCSRsInitialized) {
+ if (!isUpdatedCSRsInitialized()) {
const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF);
for (const MCPhysReg *I = CSR; *I; ++I)
UpdatedCSRs.push_back(*I);
@@ -634,7 +633,7 @@ void MachineRegisterInfo::disableCalleeSavedRegister(MCRegister Reg) {
// (no more registers should be pushed).
UpdatedCSRs.push_back(0);
- IsUpdatedCSRsInitialized = true;
+ UpdatedCSRs.setFlag(1, true);
}
// Remove the register (and its aliases from the list).
@@ -643,7 +642,7 @@ void MachineRegisterInfo::disableCalleeSavedRegister(MCRegister Reg) {
}
const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const {
- if (IsUpdatedCSRsInitialized)
+ if (isUpdatedCSRsInitialized())
return UpdatedCSRs.data();
const MCPhysReg *Regs = getTargetRegisterInfo()->getCalleeSavedRegs(MF);
@@ -656,7 +655,7 @@ const MCPhysReg *MachineRegisterInfo::getCalleeSavedRegs() const {
}
void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
- if (IsUpdatedCSRsInitialized)
+ if (isUpdatedCSRsInitialized())
UpdatedCSRs.clear();
append_range(UpdatedCSRs, CSRs);
@@ -664,7 +663,7 @@ void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
// Zero value represents the end of the register list
// (no more registers should be pushed).
UpdatedCSRs.push_back(0);
- IsUpdatedCSRsInitialized = true;
+ UpdatedCSRs.setFlag(1, true);
}
bool MachineRegisterInfo::isReservedRegUnit(MCRegUnit Unit) const {
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp
index a7f488e6e6d21..09403bd1e82d5 100644
--- a/llvm/lib/CodeGen/MachineScheduler.cpp
+++ b/llvm/lib/CodeGen/MachineScheduler.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/PriorityQueue.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -1603,7 +1604,7 @@ void ScheduleDAGMILive::collectVRegUses(SUnit &SU) {
continue;
if (!MO.readsReg())
continue;
- if (TrackLaneMasks && !MO.isUse())
+ if (getTrackLaneMasks() && !MO.isUse())
continue;
Register Reg = MO.getReg();
@@ -1611,7 +1612,7 @@ void ScheduleDAGMILive::collectVRegUses(SUnit &SU) {
continue;
// Ignore re-defs.
- if (TrackLaneMasks) {
+ if (getTrackLaneMasks()) {
bool FoundDef = false;
for (const MachineOperand &MO2 : MI.all_defs()) {
if (MO2.getReg() == Reg && !MO2.isDead()) {
@@ -2150,15 +2151,17 @@ namespace {
class BaseMemOpClusterMutation : public ScheduleDAGMutation {
struct MemOpInfo {
SUnit *SU;
- SmallVector<const MachineOperand *, 4> BaseOps;
+ llvm::SmallVectorWithFlags<const MachineOperand *, 4> BaseOps;
int64_t Offset;
LocationSize Width;
- bool OffsetIsScalable;
+ bool getOffsetIsScalable() const { return BaseOps.getFlag(0); }
+ void setOffsetIsScalable(bool Value) { BaseOps.setFlag(0, Value); }
MemOpInfo(SUnit *SU, ArrayRef<const MachineOperand *> BaseOps,
int64_t Offset, bool OffsetIsScalable, LocationSize Width)
- : SU(SU), BaseOps(BaseOps), Offset(Offset), Width(Width),
- OffsetIsScalable(OffsetIsScalable) {}
+ : SU(SU), BaseOps(decltype(this->BaseOps)::withFlags(
+ unsigned(OffsetIsScalable), BaseOps)),
+ Offset(Offset), Width(Width) {}
static bool Compare(const MachineOperand *const &A,
const MachineOperand *const &B) {
@@ -2307,8 +2310,8 @@ void BaseMemOpClusterMutation::clusterNeighboringMemOps(
}
if (!TII->shouldClusterMemOps(MemOpa.BaseOps, MemOpa.Offset,
- MemOpa.OffsetIsScalable, MemOpb.BaseOps,
- MemOpb.Offset, MemOpb.OffsetIsScalable,
+ MemOpa.getOffsetIsScalable(), MemOpb.BaseOps,
+ MemOpb.Offset, MemOpb.getOffsetIsScalable(),
ClusterLength, CurrentClusterBytes))
continue;
@@ -2688,7 +2691,7 @@ void SchedBoundary::reset() {
HazardRec.reset();
Available.clear();
Pending.clear();
- CheckPending = false;
+ setCheckPending(false);
CurrCycle = 0;
CurrMOps = 0;
MinReadyCycle = std::numeric_limits<unsigned>::max();
@@ -2697,7 +2700,7 @@ void SchedBoundary::reset() {
RetiredMOps = 0;
MaxExecutedResCount = 0;
ZoneCritResIdx = 0;
- IsResourceLimited = false;
+ setIsResourceLimited(false);
ReservedCycles.clear();
ReservedResourceSegments.clear();
ReservedCyclesIndex.clear();
@@ -3067,10 +3070,10 @@ void SchedBoundary::bumpCycle(unsigned NextCycle) {
HazardRec->RecedeCycle();
}
}
- CheckPending = true;
- IsResourceLimited =
- checkResourceLimit(SchedModel->getLatencyFactor(), getCriticalCount(),
- getScheduledLatency(), true);
+ setCheckPending(true);
+ setIsResourceLimited(checkResourceLimit(SchedModel->getLatencyFactor(),
+ getCriticalCount(),
+ getScheduledLatency(), true));
LLVM_DEBUG(dbgs() << "Cycle: " << CurrCycle << ' ' << Available.getName()
<< '\n');
@@ -3252,9 +3255,9 @@ void SchedBoundary::bumpNode(SUnit *SU) {
else
// After updating ZoneCritResIdx and ExpectedLatency, check if we're
// resource limited. If a stall occurred, bumpCycle does this.
- IsResourceLimited =
- checkResourceLimit(SchedModel->getLatencyFactor(), getCriticalCount(),
- getScheduledLatency(), true);
+ setIsResourceLimited(checkResourceLimit(SchedModel->getLatencyFactor(),
+ getCriticalCount(),
+ getScheduledLatency(), true));
// Update the reservation table.
if (HazardRec->isEnabled()) {
@@ -3265,7 +3268,7 @@ void SchedBoundary::bumpNode(SUnit *SU) {
}
HazardRec->EmitInstruction(SU);
// Scheduling an instruction may have made pending instructions available.
- CheckPending = true;
+ setCheckPending(true);
}
// Update CurrMOps after calling bumpCycle to handle stalls, since bumpCycle
@@ -3320,7 +3323,7 @@ void SchedBoundary::releasePending() {
--E;
}
}
- CheckPending = false;
+ setCheckPending(false);
}
/// Remove SU from the ready set for this boundary.
@@ -3337,7 +3340,7 @@ void SchedBoundary::removeReady(SUnit *SU) {
/// defer any nodes that now hit a hazard, and advance the cycle until at least
/// one node is ready. If multiple instructions are ready, return NULL.
SUnit *SchedBoundary::pickOnlyChoice() {
- if (CheckPending)
+ if (getCheckPending())
releasePending();
// Defer any ready instrs that now have a hazard.
@@ -3415,7 +3418,7 @@ LLVM_DUMP_METHOD void SchedBoundary::dumpScheduledState() const {
<< ResCount / ResFactor << " "
<< SchedModel->getResourceName(ZoneCritResIdx)
<< "\n ExpectedLatency: " << ExpectedLatency << "c\n"
- << (IsResourceLimited ? " - Resource" : " - Latency")
+ << (getIsResourceLimited() ? " - Resource" : " - Latency")
<< " limited.\n";
if (MISchedDumpReservedCycles)
dumpReservedCycles();
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index fa7ac4d39c335..c584939c5f0de 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -30,6 +30,7 @@
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/CodeGenCommonISel.h"
@@ -144,9 +145,16 @@ struct MachineVerifier {
const RegisterBankInfo *RBI = nullptr;
// Avoid querying the MachineFunctionProperties for each operand.
- bool isFunctionRegBankSelected = false;
- bool isFunctionSelected = false;
- bool isFunctionTracksDebugUserValues = false;
+ bool getIsFunctionRegBankSelected() const { return regMasks.getFlag(0); }
+ void setIsFunctionRegBankSelected(bool Value) { regMasks.setFlag(0, Value); }
+ bool getIsFunctionSelected() const { return regMasks.getFlag(1); }
+ void setIsFunctionSelected(bool Value) { regMasks.setFlag(1, Value); }
+ bool getIsFunctionTracksDebugUserValues() const {
+ return regMasks.getFlag(2);
+ }
+ void setIsFunctionTracksDebugUserValues(bool Value) {
+ regMasks.setFlag(2, Value);
+ }
using RegVector = SmallVector<Register, 16>;
using RegMaskVector = SmallVector<const uint32_t *, 4>;
@@ -161,7 +169,7 @@ struct MachineVerifier {
BitVector regsReserved;
RegSet regsLive;
RegVector regsDefined, regsDead, regsKilled;
- RegMaskVector regMasks;
+ llvm::SmallVectorWithFlagsFor<RegMaskVector, 3> regMasks;
SlotIndex lastIndex;
@@ -486,9 +494,9 @@ bool MachineVerifier::verify(const MachineFunction &MF) {
if (isFunctionFailedISel)
return true;
- isFunctionRegBankSelected = Props.hasRegBankSelected();
- isFunctionSelected = Props.hasSelected();
- isFunctionTracksDebugUserValues = Props.hasTracksDebugUserValues();
+ setIsFunctionRegBankSelected(Props.hasRegBankSelected());
+ setIsFunctionSelected(Props.hasSelected());
+ setIsFunctionTracksDebugUserValues(Props.hasTracksDebugUserValues());
if (PASS) {
auto *LISWrapper = PASS->getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
@@ -1107,7 +1115,7 @@ bool MachineVerifier::verifyGIntrinsicConvergence(const MachineInstr *MI) {
}
void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
- if (isFunctionSelected)
+ if (getIsFunctionSelected())
report("Unexpected generic instruction in a Selected function", MI);
const MCInstrDesc &MCID = MI->getDesc();
@@ -2783,10 +2791,10 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
// pruning unused debug operands. The final undef substitution occurs
// when debug values are allocated in LDVImpl::handleDebugValue, so
// these verifications always apply after this pass.
- if (isFunctionTracksDebugUserValues || !MO->isUse() ||
+ if (getIsFunctionTracksDebugUserValues() || !MO->isUse() ||
!MI->isDebugValue() || !MRI->def_empty(Reg)) {
// If we're post-Select, we can't have gvregs anymore.
- if (isFunctionSelected) {
+ if (getIsFunctionSelected()) {
report("Generic virtual register invalid in a Selected function",
MO, MONum);
return;
@@ -2804,7 +2812,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
const RegisterBankInfo *RBI = MF->getSubtarget().getRegBankInfo();
// If we're post-RegBankSelect, the gvreg must have a bank.
- if (!RegBank && isFunctionRegBankSelected) {
+ if (!RegBank && getIsFunctionRegBankSelected()) {
report("Generic virtual register must have a bank in a "
"RegBankSelected function",
MO, MONum);
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index 49fa0f89d616c..638c8921fd5e9 100644
--- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -22,6 +22,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -82,16 +83,26 @@ class PEIImpl {
// Save and Restore blocks of the current function. Typically there is a
// single save block, unless Windows EH funclets are involved.
MBBVector SaveBlocks;
- MBBVector RestoreBlocks;
+ llvm::SmallVectorWithFlagsFor<MBBVector, 2> RestoreBlocks;
// Flag to control whether to use the register scavenger to resolve
// frame index materialization registers. Set according to
// TRI->requiresFrameIndexScavenging() for the current function.
- bool FrameIndexVirtualScavenging = false;
+ bool getFrameIndexVirtualScavenging() const {
+ return RestoreBlocks.getFlag(0);
+ }
+ void setFrameIndexVirtualScavenging(bool Value) {
+ RestoreBlocks.setFlag(0, Value);
+ }
// Flag to control whether the scavenger should be passed even though
// FrameIndexVirtualScavenging is used.
- bool FrameIndexEliminationScavenging = false;
+ bool getFrameIndexEliminationScavenging() const {
+ return RestoreBlocks.getFlag(1);
+ }
+ void setFrameIndexEliminationScavenging(bool Value) {
+ RestoreBlocks.setFlag(1, Value);
+ }
// Emit remarks.
MachineOptimizationRemarkEmitter *ORE = nullptr;
@@ -215,7 +226,7 @@ bool PEIImpl::run(MachineFunction &MF) {
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
RS = TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr;
- FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(MF);
+ setFrameIndexVirtualScavenging(TRI->requiresFrameIndexScavenging(MF));
// Spill frame pointer and/or base pointer registers if they are clobbered.
// It is placed before call frame instruction elimination so it will not mess
@@ -266,9 +277,9 @@ bool PEIImpl::run(MachineFunction &MF) {
// and actual offsets.
if (TFI->needsFrameIndexResolution(MF)) {
// Allow the target to determine this after knowing the frame size.
- FrameIndexEliminationScavenging =
- (RS && !FrameIndexVirtualScavenging) ||
- TRI->requiresFrameIndexReplacementScavenging(MF);
+ setFrameIndexEliminationScavenging(
+ (RS && !getFrameIndexVirtualScavenging()) ||
+ TRI->requiresFrameIndexReplacementScavenging(MF));
if (TRI->eliminateFrameIndicesBackwards())
replaceFrameIndicesBackward(MF);
@@ -279,7 +290,7 @@ bool PEIImpl::run(MachineFunction &MF) {
// If register scavenging is needed, as we've enabled doing it as a
// post-pass, scavenge the virtual registers that frame index elimination
// inserted.
- if (TRI->requiresRegisterScavenging(MF) && FrameIndexVirtualScavenging)
+ if (TRI->requiresRegisterScavenging(MF) && getFrameIndexVirtualScavenging())
scavengeFrameVirtualRegs(MF, *RS);
insertZeroCallUsedRegs(MF);
@@ -1490,7 +1501,7 @@ void PEIImpl::replaceFrameIndicesBackward(MachineBasicBlock *BB,
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
- RegScavenger *LocalRS = FrameIndexEliminationScavenging ? RS : nullptr;
+ RegScavenger *LocalRS = getFrameIndexEliminationScavenging() ? RS : nullptr;
if (LocalRS)
LocalRS->enterBasicBlockEnd(*BB);
diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index 50a4f15612082..c5ca23e8092c5 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -30,6 +30,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/SparseSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -187,7 +188,8 @@ class RegAllocFastImpl {
RegAllocFastImpl(const RegAllocFilterFunc F = nullptr,
bool ClearVirtRegs_ = true)
: ShouldAllocateRegisterImpl(F), StackSlotForVirtReg(-1),
- ClearVirtRegs(ClearVirtRegs_) {}
+ RegMasks(decltype(this->RegMasks)::withFlags(
+ (unsigned(ClearVirtRegs_) << 1))) {}
private:
MachineFrameInfo *MFI = nullptr;
@@ -199,7 +201,8 @@ class RegAllocFastImpl {
/// Tied operands reach this pass unrewritten (TwoAddressInstructionPass was
/// left out of the pipeline): lower them here.
- bool LowerTiedOps = false;
+ bool getLowerTiedOps() const { return RegMasks.getFlag(0); }
+ void setLowerTiedOps(bool Value) { RegMasks.setFlag(0, Value); }
/// Basic block currently being allocated.
MachineBasicBlock *MBB = nullptr;
@@ -284,7 +287,11 @@ class RegAllocFastImpl {
SmallVector<unsigned, 8> DefOperandIndexes;
// Register masks attached to the current instruction.
- SmallVector<const uint32_t *> RegMasks;
+ llvm::SmallVectorWithFlags<
+ const uint32_t *,
+ llvm::CalculateSmallVectorDefaultInlinedElements<const uint32_t *>::value,
+ 2>
+ RegMasks;
// Assign index for each instruction to quickly determine dominance.
InstrPosIndexes PosIndexes;
@@ -351,7 +358,8 @@ class RegAllocFastImpl {
};
public:
- bool ClearVirtRegs;
+ bool getClearVirtRegs() const { return RegMasks.getFlag(1); }
+ void setClearVirtRegs(bool Value) { RegMasks.setFlag(1, Value); }
bool runOnMachineFunction(MachineFunction &MF);
@@ -451,7 +459,7 @@ class RegAllocFast : public MachineFunctionPass {
MachineFunctionProperties getSetProperties() const override {
MachineFunctionProperties P;
- if (Impl.ClearVirtRegs)
+ if (Impl.getClearVirtRegs())
P.setNoVRegs().setTiedOpsRewritten();
return P;
}
@@ -954,7 +962,7 @@ Register RegAllocFastImpl::traceCopyChain(Register Reg) const {
}
// A two-address instruction's def and tied use end up in the same
// register, so the tie continues the chain.
- Reg = LowerTiedOps ? getTiedUseReg(*Def, *DefMO) : Register();
+ Reg = getLowerTiedOps() ? getTiedUseReg(*Def, *DefMO) : Register();
if (!Reg)
return Register();
}
@@ -972,7 +980,7 @@ Register RegAllocFastImpl::traceCopies(Register VirtReg) const {
Register Reg;
if (isCoalescable(MI))
Reg = MI.getOperand(1).getReg();
- else if (LowerTiedOps)
+ else if (getLowerTiedOps())
Reg = getTiedUseReg(MI, DefMO);
if (Reg) {
Reg = traceCopyChain(Reg);
@@ -1327,7 +1335,7 @@ bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, MachineOperand &MO,
assert((!MO.isKill() || LRI->LastUse == &MI) && "Invalid kill flag");
}
- if (LowerTiedOps && MO.isTied() && lowerTiedUse(MI, MO, *LRI))
+ if (getLowerTiedOps() && MO.isTied() && lowerTiedUse(MI, MO, *LRI))
return false;
// If necessary allocate a register.
@@ -1657,7 +1665,7 @@ void RegAllocFastImpl::allocateInstruction(MachineInstr &MI) {
HasVRegDef = true;
if (MO.isEarlyClobber())
HasEarlyClobber = true;
- if (LowerTiedOps && MO.isTied())
+ if (getLowerTiedOps() && MO.isTied())
HasTiedDef = true;
if (isLiveThroughDef(MI, MO))
NeedToAssignLiveThroughs = true;
@@ -2099,8 +2107,8 @@ bool RegAllocFastImpl::runOnMachineFunction(MachineFunction &MF) {
// MIR that already went through TwoAddressInstructionPass carries
// TiedOpsRewritten, so partial pipelines (-run-pass, -start-before) follow
// the input they are given.
- LowerTiedOps = !MF.getProperties().hasTiedOpsRewritten();
- if (LowerTiedOps) {
+ setLowerTiedOps(!MF.getProperties().hasTiedOpsRewritten());
+ if (getLowerTiedOps()) {
for (MachineBasicBlock &MBB : MF)
for (MachineInstr &MI : make_early_inc_range(MBB))
if (MI.isRegSequence() || MI.isInsertSubreg())
@@ -2119,7 +2127,7 @@ bool RegAllocFastImpl::runOnMachineFunction(MachineFunction &MF) {
for (MachineBasicBlock &MBB : MF)
allocateBasicBlock(MBB);
- if (ClearVirtRegs) {
+ if (getClearVirtRegs()) {
// All machine operands and other references to virtual registers have been
// replaced. Remove the virtual registers.
MRI->clearVirtRegs();
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 685ee021dcab4..118c49bf6a1cd 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -3076,14 +3076,14 @@ bool RAGreedy::run(MachineFunction &mf) {
initializeCSRCost();
RegCosts = TRI->getRegisterCosts(*MF);
- RegClassPriorityTrumpsGlobalness =
+ setRegClassPriorityTrumpsGlobalnessFlag(
GreedyRegClassPriorityTrumpsGlobalness.getNumOccurrences()
? GreedyRegClassPriorityTrumpsGlobalness
- : TRI->regClassPriorityTrumpsGlobalness(*MF);
+ : TRI->regClassPriorityTrumpsGlobalness(*MF));
- ReverseLocalAssignment = GreedyReverseLocalAssignment.getNumOccurrences()
- ? GreedyReverseLocalAssignment
- : TRI->reverseLocalAssignment();
+ setReverseLocalAssignmentFlag(GreedyReverseLocalAssignment.getNumOccurrences()
+ ? GreedyReverseLocalAssignment
+ : TRI->reverseLocalAssignment());
ExtraInfo.emplace();
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h
index 56c9fd7f177a4..967e482477a81 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.h
+++ b/llvm/lib/CodeGen/RegAllocGreedy.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/CalcSpillWeights.h"
#include "llvm/CodeGen/LiveDebugVariables.h"
@@ -149,9 +150,9 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public RegAllocBase,
// Interface to priority advisers
bool getRegClassPriorityTrumpsGlobalness() const {
- return RegClassPriorityTrumpsGlobalness;
+ return GlobalCand.getFlag(0);
}
- bool getReverseLocalAssignment() const { return ReverseLocalAssignment; }
+ bool getReverseLocalAssignment() const { return GlobalCand.getFlag(1); }
// end (interface to priority advisers)
private:
@@ -261,7 +262,7 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public RegAllocBase,
/// Candidate info for each PhysReg in AllocationOrder.
/// This vector never shrinks, but grows to the size of the largest register
/// class.
- SmallVector<GlobalSplitCandidate, 32> GlobalCand;
+ llvm::SmallVectorWithFlags<GlobalSplitCandidate, 32, 2> GlobalCand;
enum : unsigned { NoCand = ~0u };
@@ -281,9 +282,13 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public RegAllocBase,
/// Flags for the live range priority calculation, determined once per
/// machine function.
- bool RegClassPriorityTrumpsGlobalness = false;
+ void setRegClassPriorityTrumpsGlobalnessFlag(bool Value) {
+ GlobalCand.setFlag(0, Value);
+ }
- bool ReverseLocalAssignment = false;
+ void setReverseLocalAssignmentFlag(bool Value) {
+ GlobalCand.setFlag(1, Value);
+ }
public:
RAGreedy(RequiredAnalyses &Analyses, const RegAllocFilterFunc F = nullptr);
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 14d755ebb8ef6..4ada754e419c8 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/CalcSpillWeights.h"
#include "llvm/CodeGen/LiveInterval.h"
@@ -2537,10 +2538,10 @@ class JoinVals {
/// This is true when joining sub register ranges, false when joining main
/// ranges.
- const bool SubRangeJoin;
+ bool getSubRangeJoin() const { return Vals.getFlag(0); }
/// Whether the current LiveInterval tracks subregister liveness.
- const bool TrackSubRegLiveness;
+ bool getTrackSubRegLiveness() const { return Vals.getFlag(1); }
/// Values that will be present in the final live range.
SmallVectorImpl<VNInfo *> &NewVNInfo;
@@ -2646,7 +2647,7 @@ class JoinVals {
};
/// One entry per value number in LI.
- SmallVector<Val, 8> Vals;
+ llvm::SmallVectorWithFlags<Val, 8, 2> Vals;
/// Compute the bitmask of lanes actually written by DefMI.
/// Set Redef if there are any partial register definitions that depend on the
@@ -2710,10 +2711,11 @@ class JoinVals {
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()) {}
+ Vals(decltype(this->Vals)::withFlags(
+ unsigned(SubRangeJoin) | (unsigned(TrackSubRegLiveness) << 1),
+ LR.getNumValNums())) {}
/// Analyze defs in LR and compute a value mapping in NewVNInfo.
/// Returns false if any conflicts were impossible to resolve.
@@ -2798,7 +2800,7 @@ JoinVals::followCopyChain(const VNInfo *VNI) const {
const LiveInterval &LI = LIS->getInterval(SrcReg);
const VNInfo *ValueIn;
// No subrange involved.
- if (!SubRangeJoin || !LI.hasSubRanges()) {
+ if (!getSubRangeJoin() || !LI.hasSubRanges()) {
LiveQueryResult LRQ = LI.Query(Def);
ValueIn = LRQ.valueIn();
} else {
@@ -2872,13 +2874,13 @@ JoinVals::ConflictResolution JoinVals::analyzeValue(unsigned ValNo,
const MachineInstr *DefMI = nullptr;
if (VNI->isPHIDef()) {
// Conservatively assume that all lanes in a PHI are valid.
- LaneBitmask Lanes = SubRangeJoin ? LaneBitmask::getLane(0)
- : TRI->getSubRegIndexLaneMask(SubIdx);
+ LaneBitmask Lanes = getSubRangeJoin() ? LaneBitmask::getLane(0)
+ : TRI->getSubRegIndexLaneMask(SubIdx);
V.ValidLanes = V.WriteLanes = Lanes;
} else {
DefMI = Indexes->getInstructionFromIndex(VNI->def);
assert(DefMI != nullptr);
- if (SubRangeJoin) {
+ if (getSubRangeJoin()) {
// We don't care about the lanes when joining subregister ranges.
V.WriteLanes = V.ValidLanes = LaneBitmask::getLane(0);
if (DefMI->isImplicitDef()) {
@@ -2906,7 +2908,7 @@ JoinVals::ConflictResolution JoinVals::analyzeValue(unsigned ValNo,
// not important.
if (Redef) {
V.RedefVNI = LR.Query(VNI->def).valueIn();
- assert((TrackSubRegLiveness || V.RedefVNI) &&
+ assert((getTrackSubRegLiveness() || V.RedefVNI) &&
"Instruction is reading nonexistent value");
if (V.RedefVNI != nullptr) {
computeAssignment(V.RedefVNI->id, Other);
@@ -3052,7 +3054,7 @@ JoinVals::ConflictResolution JoinVals::analyzeValue(unsigned ValNo,
// The remaining checks apply to the lanes, which aren't tracked here. This
// was already decided to be OK via the following CR_Replace condition.
// CR_Replace.
- if (SubRangeJoin)
+ if (getSubRangeJoin())
return CR_Replace;
// If the lanes written by this instruction were all undef in OtherVNI, it is
@@ -3091,7 +3093,7 @@ JoinVals::ConflictResolution JoinVals::analyzeValue(unsigned ValNo,
if ((TRI->getSubRegIndexLaneMask(Other.SubIdx) & ~V.WriteLanes).none())
return CR_Impossible;
- if (TrackSubRegLiveness) {
+ if (getTrackSubRegLiveness()) {
auto &OtherLI = LIS->getInterval(Other.Reg);
// If OtherVNI does not have subranges, it means all the lanes of OtherVNI
// share the same live range, so we just need to check whether they have
@@ -3252,7 +3254,7 @@ bool JoinVals::resolveConflicts(JoinVals &Other) {
LLVM_DEBUG(dbgs() << "\t\tconflict at " << printReg(Reg) << ':' << i << '@'
<< LR.getValNumInfo(i)->def << ' '
<< PrintLaneMask(LaneMask) << '\n');
- if (SubRangeJoin)
+ if (getSubRangeJoin())
return false;
++NumLaneConflicts;
diff --git a/llvm/lib/CodeGen/Rematerializer.cpp b/llvm/lib/CodeGen/Rematerializer.cpp
index 5d85098400f0d..9ec83b130548d 100644
--- a/llvm/lib/CodeGen/Rematerializer.cpp
+++ b/llvm/lib/CodeGen/Rematerializer.cpp
@@ -1119,7 +1119,7 @@ Printable Rematerializer::printUser(const MachineInstr *MI,
void Rollbacker::rematerializerNoteRegCreated(const Rematerializer &Remater,
RegisterIdx RegIdx) {
- if (RollingBack)
+ if (getRollingBack())
return;
assert(Remater.isRematerializedRegister(RegIdx) && "only remats are created");
Rematerializations[Remater.getOriginOf(RegIdx)].insert(RegIdx);
@@ -1127,7 +1127,7 @@ void Rollbacker::rematerializerNoteRegCreated(const Rematerializer &Remater,
void Rollbacker::rematerializerNoteRegWillBeDeleted(
const Rematerializer &Remater, RegisterIdx RegIdx) {
- if (RollingBack)
+ if (getRollingBack())
return;
const Rematerializer::Reg &Reg = Remater.getReg(RegIdx);
@@ -1183,7 +1183,7 @@ void Rollbacker::rematerializerNoteRegWillBeDeleted(
void Rollbacker::rematerializerNoteMIWillBeDeleted(
const Rematerializer &Remater, MachineInstr &MI) {
- if (RollingBack)
+ if (getRollingBack())
return;
// Previously deleted registers that reference this MI as their re-creation
@@ -1196,7 +1196,7 @@ void Rollbacker::rematerializerNoteMIWillBeDeleted(
}
void Rollbacker::rollback(Rematerializer &Remater) {
- RollingBack = true;
+ setRollingBack(true);
// As we re-create registers, map deleted definitions to re-created ones. This
// allows to replace invalid re-creation positions that reference deleted
@@ -1256,7 +1256,7 @@ void Rollbacker::rollback(Rematerializer &Remater) {
Positions.clear();
PosToIdx.clear();
Rematerializations.clear();
- RollingBack = false;
+ setRollingBack(false);
}
bool Rollbacker::isRollbackableMI(const MachineInstr &MI,
diff --git a/llvm/lib/CodeGen/ScheduleDAG.cpp b/llvm/lib/CodeGen/ScheduleDAG.cpp
index 4348153356d2c..1487c7c24b9b7 100644
--- a/llvm/lib/CodeGen/ScheduleDAG.cpp
+++ b/llvm/lib/CodeGen/ScheduleDAG.cpp
@@ -473,7 +473,7 @@ void ScheduleDAGTopologicalSort::InitDAGTopologicalSorting() {
// immediately after X in Index2Node.
// Cancel pending updates, mark as valid.
- Dirty = false;
+ setDirty(false);
Updates.clear();
Reachable.clear();
@@ -533,7 +533,7 @@ void ScheduleDAGTopologicalSort::InitDAGTopologicalSorting() {
void ScheduleDAGTopologicalSort::FixOrder() {
// Recompute from scratch after new nodes have been added.
- if (Dirty) {
+ if (getDirty()) {
InitDAGTopologicalSorting();
return;
}
@@ -548,9 +548,9 @@ void ScheduleDAGTopologicalSort::AddPredQueued(SUnit *Y, SUnit *X) {
// Recomputing the order from scratch is likely more efficient than applying
// updates one-by-one for too many updates. The current cut-off is arbitrarily
// chosen.
- Dirty = Dirty || Updates.size() > 10;
+ setDirty(getDirty() || Updates.size() > 10);
- if (Dirty)
+ if (getDirty())
return;
Updates.emplace_back(Y, X);
diff --git a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
index e5bc867cc75d4..9916bc92ccf7a 100644
--- a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -107,7 +107,8 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
const MachineLoopInfo *mli,
bool RemoveKillFlags)
: ScheduleDAG(mf), MLI(mli), MFI(mf.getFrameInfo()),
- RemoveKillFlags(RemoveKillFlags), Topo(SUnits, &ExitSU) {
+ Clusters(decltype(this->Clusters)::withFlags(unsigned(RemoveKillFlags))),
+ Topo(SUnits, &ExitSU) {
DbgValues.clear();
const TargetSubtargetInfo &ST = mf.getSubtarget();
@@ -336,7 +337,7 @@ void ScheduleDAGInstrs::addPhysRegDeps(SUnit *SU, unsigned OperIdx) {
// Push this SUnit on the use list.
for (MCRegUnit Unit : TRI->regunits(Reg))
Uses.insert(PhysRegSUOper(SU, OperIdx, Unit));
- if (RemoveKillFlags)
+ if (getRemoveKillFlags())
MO.setIsKill(false);
} else {
addPhysRegDataDeps(SU, OperIdx);
@@ -407,7 +408,7 @@ void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
LaneBitmask DefLaneMask;
LaneBitmask KillLaneMask;
- if (TrackLaneMasks) {
+ if (getTrackLaneMasks()) {
bool IsKill = MO.getSubReg() == 0 || MO.isUndef();
DefLaneMask = getLaneMaskForMO(MO);
// If we have a <read-undef> flag, none of the lane values comes from an
@@ -528,8 +529,8 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
Register Reg = MO.getReg();
// Remember the use. Data dependencies will be added when we find the def.
- LaneBitmask LaneMask = TrackLaneMasks ? getLaneMaskForMO(MO)
- : LaneBitmask::getAll();
+ LaneBitmask LaneMask =
+ getTrackLaneMasks() ? getLaneMaskForMO(MO) : LaneBitmask::getAll();
CurrentVRegUses.insert(VReg2SUnitOperIdx(Reg, LaneMask, OperIdx, SU));
// Add antidependences to the following defs of the vreg.
@@ -926,8 +927,8 @@ void ScheduleDAGDependencyBuilder::buildDeps() {
if (RPTracker) {
RegisterOperands RegOpers;
- RegOpers.collect(MI, *DAG.TRI, DAG.MRI, DAG.TrackLaneMasks, false);
- if (DAG.TrackLaneMasks) {
+ RegOpers.collect(MI, *DAG.TRI, DAG.MRI, DAG.getTrackLaneMasks(), false);
+ if (DAG.getTrackLaneMasks()) {
SlotIndex SlotIdx = LIS->getInstructionIndex(MI);
RegOpers.adjustLaneLiveness(*LIS, DAG.MRI, SlotIdx);
} else if (LIS) {
@@ -944,7 +945,7 @@ void ScheduleDAGDependencyBuilder::buildDeps() {
RPTracker->recede(RegOpers);
}
- assert((DAG.CanHandleTerminators ||
+ assert((DAG.getCanHandleTerminators() ||
(!MI.isTerminator() && !MI.isPosition())) &&
"Cannot schedule terminators or labels!");
@@ -1118,7 +1119,7 @@ void ScheduleDAGInstrs::buildSchedGraph(AAResults *AA,
const TargetSubtargetInfo &ST = MF.getSubtarget();
bool UseAA =
EnableAASchedMI.getNumOccurrences() > 0 ? EnableAASchedMI : ST.useAA();
- this->TrackLaneMasks = TrackLaneMasks;
+ this->setTrackLaneMasks(TrackLaneMasks);
MISUnitMap.clear();
ScheduleDAG::clearDAG();
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index 5ea69ea78d434..d04667ea39026 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -138,7 +139,8 @@ namespace {
class ScheduleDAGRRList : public ScheduleDAGSDNodes {
private:
/// NeedLatency - True if the scheduler will make use of latency information.
- bool NeedLatency;
+ bool getNeedLatency() const { return Interferences.getFlag(0); }
+ void setNeedLatency(bool Value) { Interferences.setFlag(0, Value); }
/// AvailableQueue - The priority queue to use for the available SUnits.
SchedulingPriorityQueue *AvailableQueue;
@@ -171,7 +173,7 @@ class ScheduleDAGRRList : public ScheduleDAGSDNodes {
// Collect interferences between physical register use/defs.
// Each interference is an SUnit and set of physical registers.
- SmallVector<SUnit*, 4> Interferences;
+ llvm::SmallVectorWithFlags<SUnit *, 4> Interferences;
using LRegsMapT = DenseMap<SUnit *, SmallVector<unsigned, 4>>;
@@ -189,10 +191,12 @@ class ScheduleDAGRRList : public ScheduleDAGSDNodes {
ScheduleDAGRRList(MachineFunction &mf, bool needlatency,
SchedulingPriorityQueue *availqueue,
CodeGenOptLevel OptLevel)
- : ScheduleDAGSDNodes(mf), NeedLatency(needlatency),
- AvailableQueue(availqueue), Topo(SUnits, nullptr) {
+ : ScheduleDAGSDNodes(mf), AvailableQueue(availqueue),
+ Interferences(
+ decltype(this->Interferences)::withFlags(unsigned(needlatency))),
+ Topo(SUnits, nullptr) {
const TargetSubtargetInfo &STI = mf.getSubtarget();
- if (DisableSchedCycles || !NeedLatency)
+ if (DisableSchedCycles || !getNeedLatency())
HazardRec = new ScheduleHazardRecognizer();
else
HazardRec = STI.getInstrInfo()->CreateTargetHazardRecognizer(&STI, this);
@@ -286,9 +290,7 @@ class ScheduleDAGRRList : public ScheduleDAGSDNodes {
/// forceUnitLatencies - Register-pressure-reducing scheduling doesn't
/// need actual latency information but the hybrid scheduler does.
- bool forceUnitLatencies() const override {
- return !NeedLatency;
- }
+ bool forceUnitLatencies() const override { return !getNeedLatency(); }
};
} // end anonymous namespace
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 2d5a55a799c02..d24ffe821c9c4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -15253,15 +15253,7 @@ void SelectionDAG::createOperands(SDNode *Node, ArrayRef<SDValue> Vals) {
SDValue SelectionDAG::getTokenFactor(const SDLoc &DL,
SmallVectorImpl<SDValue> &Vals) {
- size_t Limit = SDNode::getMaxNumOperands();
- while (Vals.size() > Limit) {
- unsigned SliceIdx = Vals.size() - Limit;
- auto ExtractedTFs = ArrayRef<SDValue>(Vals).slice(SliceIdx, Limit);
- SDValue NewTF = getNode(ISD::TokenFactor, DL, MVT::Other, ExtractedTFs);
- Vals.erase(Vals.begin() + SliceIdx, Vals.end());
- Vals.emplace_back(NewTF);
- }
- return getNode(ISD::TokenFactor, DL, MVT::Other, Vals);
+ return getTokenFactorImpl(DL, Vals);
}
SDValue SelectionDAG::getIdentityElement(unsigned Opcode, const SDLoc &DL,
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index b595de3734bb9..a753a320100cb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -1111,10 +1112,10 @@ void SelectionDAGBuilder::init(GCFunctionInfo *gfi, BatchAAResults *aa,
LPadToCallSiteMap.clear();
this->TTI = &TTI;
SL->init(DAG.getTargetLoweringInfo(), TM, DAG.getDataLayout());
- AssignmentTrackingEnabled = isAssignmentTrackingEnabled(
- *DAG.getMachineFunction().getFunction().getParent());
- CanDescribeGlobalAddressInLocationList =
- canDescribeGlobalAddressInLocationList(DAG.getMachineFunction());
+ setAssignmentTrackingEnabled(isAssignmentTrackingEnabled(
+ *DAG.getMachineFunction().getFunction().getParent()));
+ setCanDescribeGlobalAddressInLocationList(
+ canDescribeGlobalAddressInLocationList(DAG.getMachineFunction()));
}
void SelectionDAGBuilder::clear() {
@@ -1125,7 +1126,7 @@ void SelectionDAGBuilder::clear() {
PendingConstrainedFP.clear();
PendingConstrainedFPStrict.clear();
CurInst = nullptr;
- HasTailCall = false;
+ setHasTailCall(false);
SDNodeOrder = LowestSDNodeOrder;
StatepointLowering.clear();
}
@@ -1135,7 +1136,8 @@ void SelectionDAGBuilder::clearDanglingDebugInfo() {
}
// Update DAG root to include dependencies on Pending chains.
-SDValue SelectionDAGBuilder::updateRoot(SmallVectorImpl<SDValue> &Pending) {
+template <typename PendingT>
+SDValue SelectionDAGBuilder::updateRoot(PendingT &Pending) {
SDValue Root = DAG.getRoot();
if (Pending.empty())
@@ -1395,7 +1397,7 @@ void SelectionDAGBuilder::visit(const Instruction &I) {
visit(I.getOpcode(), I);
- if (!I.isTerminator() && !HasTailCall &&
+ if (!I.isTerminator() && !getHasTailCall() &&
!isa<GCStatepointInst>(I)) // statepoints handle their exports internally
CopyToExportRegsIfNeeded(&I);
@@ -1702,7 +1704,7 @@ bool SelectionDAGBuilder::handleDebugValue(ArrayRef<const Value *> Values,
// way falls through to be described by whatever materializes it instead.
// So does one that a location list could not name, should the variable
// need one; salvageUnresolvedDbgValue names it if nothing materializes it.
- if (CanDescribeGlobalAddressInLocationList)
+ if (getCanDescribeGlobalAddressInLocationList())
if (const GlobalValue *GV = getGlobalAddressDbgOperand(
V, Expr, OpIdx, DAG.getMachineFunction())) {
LocationOps.emplace_back(SDDbgOperand::fromGlobalAddr(GV));
@@ -3410,13 +3412,13 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B,
MachineBasicBlock* MBB = B.Cases[0].ThisBB;
- if (!B.FallthroughUnreachable)
+ if (!B.getFallthroughUnreachable())
addSuccessorWithProb(SwitchBB, B.Default, B.DefaultProb);
addSuccessorWithProb(SwitchBB, MBB, B.Prob);
SwitchBB->normalizeSuccProbs();
SDValue Root = CopyTo;
- if (!B.FallthroughUnreachable) {
+ if (!B.getFallthroughUnreachable()) {
// Conditional branch to the default block.
SDValue RangeCmp = DAG.getSetCC(dl,
TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
@@ -8050,7 +8052,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
DAG.getExternalSymbol(TrapFuncName.data(),
TLI.getPointerTy(DAG.getDataLayout())),
std::move(Args));
- CLI.NoMerge = I.hasFnAttr(Attribute::NoMerge);
+ CLI.setNoMerge(I.hasFnAttr(Attribute::NoMerge));
std::pair<SDValue, SDValue> Result = TLI.LowerCallTo(CLI);
DAG.setRoot(Result.second);
return;
@@ -8454,7 +8456,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
0);
DAG.setRoot(N);
setValue(&I, N);
- HasTailCall = true;
+ setHasTailCall(true);
return;
}
@@ -8524,7 +8526,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
assert(!Result.first.getNode() && !Result.second.getNode() &&
"Should've lowered as tail call");
- HasTailCall = true;
+ setHasTailCall(true);
return;
}
case Intrinsic::amdgcn_call_whole_wave: {
@@ -9360,7 +9362,7 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
std::pair<SDValue, SDValue> Result = TLI.LowerCallTo(CLI);
- assert((CLI.IsTailCall || Result.second.getNode()) &&
+ assert((CLI.getIsTailCall() || Result.second.getNode()) &&
"Non-null chain expected with non-tail call!");
assert((Result.second.getNode() || !Result.first.getNode()) &&
"Null value expected with tail call!");
@@ -9368,7 +9370,7 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
if (!Result.second.getNode()) {
// As a special case, a null chain means that a tail call has been emitted
// and the DAG root is already updated.
- HasTailCall = true;
+ setHasTailCall(true);
// Since there's no actual continuation from this block, nothing can be
// relying on us setting vregs for them.
@@ -10453,10 +10455,14 @@ static bool isFunction(SDValue Op) {
namespace {
struct ConstraintDecisionInfo {
- SmallVector<SDISelAsmOperandInfo, 16> ConstraintOperands;
+ llvm::SmallVectorWithFlags<SDISelAsmOperandInfo, 16> ConstraintOperands;
std::vector<SDValue> AsmNodeOperands;
SDValue Glue, Chain;
- bool HasSideEffect = false;
+ bool getHasSideEffect() const { return ConstraintOperands.getFlag(0); }
+ bool setHasSideEffect(bool Value) {
+ ConstraintOperands.setFlag(0, Value);
+ return Value;
+ }
MCSymbol *BeginLabel = nullptr;
SmallVector<char> Buffer;
@@ -10480,8 +10486,8 @@ constructOperandInfo(ConstraintDecisionInfo &Info,
if (OpInfo.CallOperandVal)
OpInfo.CallOperand = Builder.getValue(OpInfo.CallOperandVal);
- if (!Info.HasSideEffect)
- Info.HasSideEffect = OpInfo.hasMemory(TLI);
+ if (!Info.getHasSideEffect())
+ Info.setHasSideEffect(OpInfo.hasMemory(TLI));
// Determine if this InlineAsm MayLoad or MayStore based on the constraints.
// FIXME: Could we compute this on OpInfo rather than T?
@@ -10855,13 +10861,13 @@ determineConstraints(ConstraintDecisionInfo &Info,
ExtraFlags ExtraInfo(Call);
// First pass: Construct operand info objects.
- Info.HasSideEffect = IA->hasSideEffects();
+ Info.setHasSideEffect(IA->hasSideEffects());
if (constructOperandInfo(Info, TargetConstraints, Builder, TLI, ExtraInfo))
return true;
// We won't need to flush pending loads if this asm doesn't touch
// memory and is nonvolatile.
- Info.Chain = Info.HasSideEffect ? Builder.getRoot() : DAG.getRoot();
+ Info.Chain = Info.getHasSideEffect() ? Builder.getRoot() : DAG.getRoot();
bool IsCallBr = isa<CallBrInst>(Call);
bool EmitEHLabels = isa<InvokeInst>(Call);
@@ -11038,7 +11044,7 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call,
Chain = lowerEndEH(Chain, II, EHPadBB, Info.BeginLabel);
// Only Update Root if inline assembly has a memory effect.
- if (ResultValues.empty() || Info.HasSideEffect || !OutChains.empty() ||
+ if (ResultValues.empty() || Info.getHasSideEffect() || !OutChains.empty() ||
IsCallBr || isa<InvokeInst>(Call))
DAG.setRoot(Chain);
}
@@ -11526,11 +11532,11 @@ void SelectionDAGBuilder::visitVectorReduce(const CallInst &I,
/// value of the given call.
static AttributeList getReturnAttrs(TargetLowering::CallLoweringInfo &CLI) {
SmallVector<Attribute::AttrKind, 2> Attrs;
- if (CLI.RetSExt)
+ if (CLI.getRetSExt())
Attrs.push_back(Attribute::SExt);
- if (CLI.RetZExt)
+ if (CLI.getRetZExt())
Attrs.push_back(Attribute::ZExt);
- if (CLI.IsInReg)
+ if (CLI.getIsInReg())
Attrs.push_back(Attribute::InReg);
return AttributeList::get(CLI.RetTy->getContext(), AttributeList::ReturnIndex,
@@ -11562,7 +11568,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
RetVTs.push_back(getValueType(DL, Ty));
}
- if (CLI.IsPostTypeLegalization) {
+ if (CLI.getIsPostTypeLegalizationFlag()) {
// If we are lowering a libcall after legalization, split the return type.
SmallVector<Type *, 4> OldRetOrigTys;
SmallVector<EVT, 4> OldRetVTs;
@@ -11589,7 +11595,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
bool CanLowerReturn =
this->CanLowerReturn(CLI.CallConv, CLI.DAG.getMachineFunction(),
- CLI.IsVarArg, Outs, Context, CLI.RetTy);
+ CLI.getIsVarArg(), Outs, Context, CLI.RetTy);
SDValue DemoteStackSlot;
int DemoteStackIdx = -100;
@@ -11615,10 +11621,10 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
// sret demotion isn't compatible with tail-calls, since the sret argument
// points into the callers stack frame.
- CLI.IsTailCall = false;
+ CLI.setIsTailCall(false);
} else {
bool NeedsRegBlock = functionArgumentNeedsConsecutiveRegisters(
- CLI.RetTy, CLI.CallConv, CLI.IsVarArg, DL);
+ CLI.RetTy, CLI.CallConv, CLI.getIsVarArg(), DL);
for (unsigned I = 0, E = RetVTs.size(); I != E; ++I) {
ISD::ArgFlagsTy Flags;
if (NeedsRegBlock) {
@@ -11632,17 +11638,18 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
getNumRegistersForCallingConv(Context, CLI.CallConv, VT);
for (unsigned i = 0; i != NumRegs; ++i) {
ISD::InputArg Ret(Flags, RegisterVT, VT, RetOrigTys[I],
- CLI.IsReturnValueUsed, ISD::InputArg::NoArgIndex, 0);
+ CLI.getIsReturnValueUsed(), ISD::InputArg::NoArgIndex,
+ 0);
if (CLI.RetTy->isPointerTy()) {
Ret.Flags.setPointer();
Ret.Flags.setPointerAddrSpace(
cast<PointerType>(CLI.RetTy)->getAddressSpace());
}
- if (CLI.RetSExt)
+ if (CLI.getRetSExt())
Ret.Flags.setSExt();
- if (CLI.RetZExt)
+ if (CLI.getRetZExt())
Ret.Flags.setZExt();
- if (CLI.IsInReg)
+ if (CLI.getIsInReg())
Ret.Flags.setInReg();
CLI.Ins.push_back(Ret);
}
@@ -11675,7 +11682,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
if (Args[i].IsByVal)
FinalType = Args[i].IndirectType;
bool NeedsRegBlock = functionArgumentNeedsConsecutiveRegisters(
- FinalType, CLI.CallConv, CLI.IsVarArg, DL);
+ FinalType, CLI.CallConv, CLI.getIsVarArg(), DL);
for (unsigned Value = 0, NumValues = OrigArgTys.size(); Value != NumValues;
++Value) {
Type *OrigArgTy = OrigArgTys[Value];
@@ -11805,8 +11812,9 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
// parameter extension method is not compatible with the return
// extension method
if ((NumParts * PartVT.getSizeInBits() == VT.getSizeInBits()) ||
- (ExtendKind != ISD::ANY_EXTEND && CLI.RetSExt == Args[i].IsSExt &&
- CLI.RetZExt == Args[i].IsZExt))
+ (ExtendKind != ISD::ANY_EXTEND &&
+ CLI.getRetSExt() == Args[i].IsSExt &&
+ CLI.getRetZExt() == Args[i].IsZExt))
Flags.setReturned();
}
@@ -11841,21 +11849,22 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
CLI.Chain = LowerCall(CLI, InVals);
// Update CLI.InVals to use outside of this function.
- CLI.InVals = InVals;
+ if (CLI.InVals.data() != InVals.data())
+ CLI.InVals.assign(InVals.begin(), InVals.end());
// Verify that the target's LowerCall behaved as expected.
assert(CLI.Chain.getNode() && CLI.Chain.getValueType() == MVT::Other &&
"LowerCall didn't return a valid chain!");
- assert((!CLI.IsTailCall || InVals.empty()) &&
+ assert((!CLI.getIsTailCall() || InVals.empty()) &&
"LowerCall emitted a return value for a tail call!");
- assert((CLI.IsTailCall || InVals.size() == CLI.Ins.size()) &&
+ assert((CLI.getIsTailCall() || InVals.size() == CLI.Ins.size()) &&
"LowerCall didn't emit the correct number of values!");
// For a tail call, the return value is merely live-out and there aren't
// any nodes in the DAG representing it. Return a special value to
// indicate that a tail call has been emitted and no more Instructions
// should be processed in the current block.
- if (CLI.IsTailCall) {
+ if (CLI.getIsTailCall()) {
CLI.DAG.setRoot(CLI.Chain);
return std::make_pair(SDValue(), SDValue());
}
@@ -11900,9 +11909,9 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
// Collect the legal value parts into potentially illegal values
// that correspond to the original function's return values.
std::optional<ISD::NodeType> AssertOp;
- if (CLI.RetSExt)
+ if (CLI.getRetSExt())
AssertOp = ISD::AssertSext;
- else if (CLI.RetZExt)
+ else if (CLI.getRetZExt())
AssertOp = ISD::AssertZext;
unsigned CurReg = 0;
for (EVT VT : RetVTs) {
@@ -12642,7 +12651,7 @@ void SelectionDAGBuilder::updateDAGForMaybeTailCall(SDValue MaybeTC) {
if (MaybeTC.getNode() != nullptr)
DAG.setRoot(MaybeTC);
else
- HasTailCall = true;
+ setHasTailCall(true);
}
void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W, Value *Cond,
@@ -12839,18 +12848,18 @@ void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W, Value *Cond,
// 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) {
+ if (!BTB->getContiguousRange()) {
BTB->Prob += DefaultProb / 2;
BTB->DefaultProb -= DefaultProb / 2;
}
if (FallthroughUnreachable)
- BTB->FallthroughUnreachable = true;
+ BTB->setFallthroughUnreachable(true);
// If we're in the right place, emit the bit test header right now.
if (CurMBB == SwitchMBB) {
visitBitTestHeader(*BTB, SwitchMBB);
- BTB->Emitted = true;
+ BTB->setEmitted(true);
}
break;
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index c9bb96b86b7bd..1b7a4bbae9b0a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
#include "llvm/CodeGen/CodeGenCommonISel.h"
#include "llvm/CodeGen/ISDOpcodes.h"
@@ -162,11 +163,21 @@ class SelectionDAGBuilder {
/// Cache the module flag for whether we should use debug-info assignment
/// tracking.
- bool AssignmentTrackingEnabled = false;
+ bool getAssignmentTrackingEnabled() const {
+ return PendingConstrainedFPStrict.getFlag(0);
+ }
+ void setAssignmentTrackingEnabled(bool Value) {
+ PendingConstrainedFPStrict.setFlag(0, Value);
+ }
/// Cache whether a debug value can name the address of a global directly,
/// rather than holding out for a register with it.
- bool CanDescribeGlobalAddressInLocationList = false;
+ bool getCanDescribeGlobalAddressInLocationList() const {
+ return PendingConstrainedFPStrict.getFlag(1);
+ }
+ void setCanDescribeGlobalAddressInLocationList(bool Value) {
+ PendingConstrainedFPStrict.setFlag(1, Value);
+ }
public:
/// Loads are not emitted to the program immediately. We bunch them up and
@@ -194,10 +205,10 @@ class SelectionDAGBuilder {
/// terminator instruction (like PendingExports). We track the latter
/// set of nodes in a separate list.
SmallVector<SDValue, 8> PendingConstrainedFP;
- SmallVector<SDValue, 8> PendingConstrainedFPStrict;
+ llvm::SmallVectorWithFlags<SDValue, 8, 3> PendingConstrainedFPStrict;
/// Update root to include all chains from the Pending list.
- SDValue updateRoot(SmallVectorImpl<SDValue> &Pending);
+ template <typename PendingT> SDValue updateRoot(PendingT &Pending);
/// Given a node representing a floating-point operation and its specified
/// exception behavior, this either updates the root or stores the node in
@@ -279,7 +290,11 @@ class SelectionDAGBuilder {
/// This is set to true if a call in the current block has been translated as
/// a tail call. In this case, no subsequent DAG nodes should be created.
- bool HasTailCall = false;
+ bool getHasTailCall() const { return PendingConstrainedFPStrict.getFlag(2); }
+ bool setHasTailCall(bool Value) {
+ PendingConstrainedFPStrict.setFlag(2, Value);
+ return Value;
+ }
LLVMContext *Context = nullptr;
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 84958ac50ab4f..e8376a0c33556 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -885,7 +886,8 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
// Lower the instructions. If a call is emitted as a tail call, cease emitting
// nodes for this block. If an instruction is elided, don't emit it, but do
// handle any debug-info attached to it.
- for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall; ++I) {
+ for (BasicBlock::const_iterator I = Begin; I != End && !SDB->getHasTailCall();
+ ++I) {
if (!ElidedArgCopyInstrs.count(&*I))
SDB->visit(*I);
else
@@ -894,7 +896,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
// Make sure the root of the DAG is up-to-date.
CurDAG->setRoot(SDB->getControlRoot());
- HadTailCall = SDB->HasTailCall;
+ HadTailCall = SDB->getHasTailCall();
SDB->resolveOrClearDbgInfo();
SDB->clear();
@@ -2048,7 +2050,7 @@ SelectionDAGISel::FinishBasicBlock() {
// Lower each BitTestBlock.
for (auto &BTB : SDB->SL->BitTestCases) {
// Lower header first, if it wasn't already lowered
- if (!BTB.Emitted) {
+ if (!BTB.getEmitted()) {
// Set the current basic block to the mbb we wish to insert the code into
FuncInfo->MBB = BTB.Parent;
FuncInfo->InsertPt = FuncInfo->MBB->end();
@@ -2076,7 +2078,8 @@ SelectionDAGISel::FinishBasicBlock() {
// test, and delete the last bit test.
MachineBasicBlock *NextMBB;
- if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
+ if ((BTB.getContiguousRange() || BTB.getFallthroughUnreachable()) &&
+ j + 2 == ej) {
// Second-to-last bit-test with contiguous range or omitted range
// check: fall through to the target of the final bit test.
NextMBB = BTB.Cases[j + 1].TargetBB;
@@ -2095,7 +2098,8 @@ SelectionDAGISel::FinishBasicBlock() {
SDB->clear();
CodeGenAndEmitDAG();
- if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
+ if ((BTB.getContiguousRange() || BTB.getFallthroughUnreachable()) &&
+ j + 2 == ej) {
// Since we're not going to use the final bit test, remove it.
BTB.Cases.pop_back();
break;
@@ -2113,9 +2117,9 @@ SelectionDAGISel::FinishBasicBlock() {
// from last "case" BB, unless the latter was skipped.
if (PHIBB == BTB.Default) {
PHI.addReg(P.second).addMBB(BTB.Parent);
- if (!BTB.ContiguousRange) {
+ if (!BTB.getContiguousRange()) {
PHI.addReg(P.second).addMBB(BTB.Cases.back().ThisBB);
- }
+ }
}
// One of "cases" BB.
for (const SwitchCG::BitTestCase &BT : BTB.Cases) {
@@ -3290,7 +3294,7 @@ struct MatchScope {
unsigned FailIndex;
/// NodeStack - The node stack when the scope was formed.
- SmallVector<SDValue, 4> NodeStack;
+ llvm::SmallVectorWithFlags<SDValue, 4> NodeStack;
/// NumRecordedNodes - The number of recorded nodes when the scope was formed.
unsigned NumRecordedNodes;
@@ -3302,7 +3306,8 @@ struct MatchScope {
SDValue InputChain, InputGlue;
/// HasChainNodesMatched - True if the ChainNodesMatched list is non-empty.
- bool HasChainNodesMatched;
+ bool getHasChainNodesMatched() const { return NodeStack.getFlag(0); }
+ void setHasChainNodesMatched(bool Value) { NodeStack.setFlag(0, Value); }
};
/// \A DAG update listener to keep the matching state
@@ -3574,7 +3579,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
NewEntry.NumMatchedMemRefs = MatchedMemRefs.size();
NewEntry.InputChain = InputChain;
NewEntry.InputGlue = InputGlue;
- NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty();
+ NewEntry.setHasChainNodesMatched(!ChainNodesMatched.empty());
continue;
}
case OPC_RecordNode: {
@@ -4556,7 +4561,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
InputChain = LastScope.InputChain;
InputGlue = LastScope.InputGlue;
- if (!LastScope.HasChainNodesMatched)
+ if (!LastScope.getHasChainNodesMatched())
ChainNodesMatched.clear();
// Check to see what the offset is at the new MatcherIndex. If it is zero
diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index b7a9464c6661c..fc31073b5de2a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -1183,7 +1183,7 @@ void SelectionDAGBuilder::LowerCallSiteWithDeoptBundleImpl(
ForceVoidReturnTy ? Type::getVoidTy(*DAG.getContext()) : Call->getType(),
Call->getAttributes().getRetAttrs(), /*IsPatchPoint=*/false);
if (!VarArgDisallowed)
- SI.CLI.IsVarArg = Call->getFunctionType()->isVarArg();
+ SI.CLI.setIsVarArg(Call->getFunctionType()->isVarArg());
auto DeoptBundle = *Call->getOperandBundle(LLVMContext::OB_deopt);
diff --git a/llvm/lib/CodeGen/TargetSchedule.cpp b/llvm/lib/CodeGen/TargetSchedule.cpp
index 54bbf8ac60561..ba3a17fea12e5 100644
--- a/llvm/lib/CodeGen/TargetSchedule.cpp
+++ b/llvm/lib/CodeGen/TargetSchedule.cpp
@@ -33,11 +33,11 @@ static cl::opt<bool> ForceEnableIntervals(
cl::desc("Force the use of resource intervals in the schedule model"));
bool TargetSchedModel::hasInstrSchedModel() const {
- return EnableSchedModel && SchedModel.hasInstrSchedModel();
+ return getEnableSchedModel() && SchedModel.hasInstrSchedModel();
}
bool TargetSchedModel::hasInstrItineraries() const {
- return EnableSchedItins && !InstrItins.isEmpty();
+ return getEnableSchedItins() && !InstrItins.isEmpty();
}
void TargetSchedModel::init(const TargetSubtargetInfo *TSInfo,
@@ -47,8 +47,8 @@ void TargetSchedModel::init(const TargetSubtargetInfo *TSInfo,
TII = TSInfo->getInstrInfo();
STI->initInstrItins(InstrItins);
- EnableSchedModel = EnableSModel;
- EnableSchedItins = EnableSItins;
+ setEnableSchedModel(EnableSModel);
+ setEnableSchedItins(EnableSItins);
unsigned NumRes = SchedModel.getNumProcResourceKinds();
ResourceFactors.resize(NumRes);
diff --git a/llvm/lib/DTLTO/DTLTO.cpp b/llvm/lib/DTLTO/DTLTO.cpp
index 669ba75c80d4b..7ae124a90b32d 100644
--- a/llvm/lib/DTLTO/DTLTO.cpp
+++ b/llvm/lib/DTLTO/DTLTO.cpp
@@ -75,7 +75,7 @@ void lto::DTLTO::waitForCleanup() { BackgroundDeleter.waitForTasks(); }
// Remove temporary files created to enable distribution.
void lto::DTLTO::cleanup() {
- if (SaveTemps)
+ if (getSaveTemps())
return;
BackgroundDeleter.removeFiles(std::move(CleanupList), Conf);
@@ -197,16 +197,16 @@ Error lto::DTLTO::prepareDtltoJob(StringRef ModulePath, unsigned Task) {
if (OnIndexWriteCb)
OnIndexWriteCb(J.SummaryIndexPath.str());
- if (ShouldEmitImportFiles)
+ if (getShouldEmitImportFiles())
if (Error Err = save(join(J.ImportsFilesList, "\n"), J.ImportsPath))
return Err;
- if (!SaveTemps) {
+ if (!getSaveTemps()) {
if (!J.Cached)
addToCleanup(J.NativeObjectPath.str());
- if (!ShouldEmitIndexFiles)
+ if (!getShouldEmitIndexFiles())
addToCleanup(J.SummaryIndexPath.str());
- if (!ShouldEmitImportFiles)
+ if (!getShouldEmitImportFiles())
addToCleanup(J.ImportsPath.str());
}
return Error::success();
@@ -283,7 +283,7 @@ Error lto::DTLTO::performCodegen() {
// Build common remote compiler options.
buildCommonRemoteCompilerOptions();
- DistributionDriver Distributor(DistributorParams, Jobs, SaveTemps,
+ DistributionDriver Distributor(DistributorParams, Jobs, getSaveTemps(),
[&](StringRef S) { addToCleanup(S); });
if (CachedJobs.load() < Jobs.size()) {
diff --git a/llvm/lib/DTLTO/DTLTOInputFiles.cpp b/llvm/lib/DTLTO/DTLTOInputFiles.cpp
index b940bad4b8635..540ddcde69d2f 100644
--- a/llvm/lib/DTLTO/DTLTOInputFiles.cpp
+++ b/llvm/lib/DTLTO/DTLTOInputFiles.cpp
@@ -216,7 +216,7 @@ Error lto::DTLTO::extractLTOInputs() {
if (Error Err = save(Buf.getBuffer(), ModuleID))
return Err;
// Cleanup this file on abnormal process exit.
- if (!SaveTemps)
+ if (!getSaveTemps())
addToCleanup(ModuleID);
}
return Error::success();
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index df69afdd88eea..55bff4729ee6d 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -614,7 +614,7 @@ unsigned DWARFLinker::shouldKeepVariableDIE(AddressesMap &RelocMgr,
MyInfo.InDebugMap = true;
if (((Flags & TF_InFunctionScope) &&
- !LLVM_UNLIKELY(Options.KeepFunctionForStatic)))
+ !LLVM_UNLIKELY(Options.getKeepFunctionForStatic())))
return Flags;
if (Options.Verbose) {
@@ -1312,7 +1312,8 @@ void DWARFLinker::DIECloner::cloneExpression(
assert(RealSize == ULEBsize && "padding failed");
ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
OutputBuffer.append(ULEBbytes.begin(), ULEBbytes.end());
- } else if (!Linker.Options.Update && Op.getCode() == dwarf::DW_OP_addrx) {
+ } else if (!Linker.Options.getUpdate() &&
+ Op.getCode() == dwarf::DW_OP_addrx) {
if (std::optional<object::SectionedAddress> SA =
Unit.getOrigUnit().getAddrOffsetSectionItem(
Op.getRawOperand(0))) {
@@ -1335,7 +1336,8 @@ void DWARFLinker::DIECloner::cloneExpression(
OutputBuffer.append(AddressBytes.begin(), AddressBytes.end());
} else
Linker.reportWarning("cannot read DW_OP_addrx operand.", File);
- } else if (!Linker.Options.Update && Op.getCode() == dwarf::DW_OP_constx) {
+ } else if (!Linker.Options.getUpdate() &&
+ Op.getCode() == dwarf::DW_OP_constx) {
if (std::optional<object::SectionedAddress> SA =
Unit.getOrigUnit().getAddrOffsetSectionItem(
Op.getRawOperand(0))) {
@@ -1475,7 +1477,7 @@ unsigned DWARFLinker::DIECloner::cloneAddressAttribute(
if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
Info.HasLowPc = true;
- if (LLVM_UNLIKELY(Linker.Options.Update)) {
+ if (LLVM_UNLIKELY(Linker.Options.getUpdate())) {
Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr),
dwarf::Form(AttrSpec.Form), DIEInteger(Val.getRawUValue()));
return AttrSize;
@@ -1589,7 +1591,7 @@ unsigned DWARFLinker::DIECloner::cloneScalarAttribute(
return Unit.getOrigUnit().getFormParams().getDwarfOffsetByteSize();
}
- if (LLVM_UNLIKELY(Linker.Options.Update)) {
+ if (LLVM_UNLIKELY(Linker.Options.getUpdate())) {
if (auto OptionalValue = Val.getAsUnsignedConstant())
Value = *OptionalValue;
else if (auto OptionalValue = Val.getAsSignedConstant())
@@ -2085,7 +2087,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
/// to point at the new entries.
Error DWARFLinker::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
DebugDieValuePool &AddrPool) const {
- if (LLVM_UNLIKELY(Options.Update))
+ if (LLVM_UNLIKELY(Options.getUpdate()))
return Error::success();
const auto &FunctionRanges = Unit.getFunctionRanges();
@@ -2158,7 +2160,7 @@ Error DWARFLinker::generateUnitRanges(CompileUnit &Unit, const DWARFFile &File,
Error DWARFLinker::DIECloner::generateUnitLocations(
CompileUnit &Unit, const DWARFFile &File,
ExpressionHandlerRef ExprHandler) {
- if (LLVM_UNLIKELY(Linker.Options.Update))
+ if (LLVM_UNLIKELY(Linker.Options.getUpdate()))
return Error::success();
const LocListAttributesTy &AllLocListAttributes =
@@ -2226,7 +2228,7 @@ static void patchAddrBase(DIE &Die, DIEInteger Offset) {
Error DWARFLinker::DIECloner::emitDebugAddrSection(
CompileUnit &Unit, const uint16_t DwarfVersion) const {
- if (LLVM_UNLIKELY(Linker.Options.Update))
+ if (LLVM_UNLIKELY(Linker.Options.getUpdate()))
return Error::success();
if (DwarfVersion < 5)
@@ -2353,7 +2355,7 @@ Error DWARFLinker::DIECloner::generateLineTableForUnit(CompileUnit &Unit) {
LineTable.Prologue = LT->Prologue;
// Set Line Table Rows.
- if (Linker.Options.Update) {
+ if (Linker.Options.getUpdate()) {
LineTable.Rows = LT->Rows;
// If all the line table contains is a DW_LNE_end_sequence, clear the line
// table rows, it will be inserted again in the DWARFStreamer.
@@ -2899,8 +2901,8 @@ Error DWARFLinker::loadClangModule(
}
// Add this module.
- Unit = std::make_unique<CompileUnit>(*CU, UniqueUnitID++, !Options.NoODR,
- ModuleName);
+ Unit = std::make_unique<CompileUnit>(*CU, UniqueUnitID++,
+ !Options.getNoODR(), ModuleName);
}
}
@@ -2943,7 +2945,7 @@ Expected<uint64_t> DWARFLinker::DIECloner::cloneAllCompileUnits(
Linker.emitAcceleratorEntriesForUnit(*CurrentUnit);
- if (LLVM_UNLIKELY(Linker.Options.Update))
+ if (LLVM_UNLIKELY(Linker.Options.getUpdate()))
continue;
if (Error E = Linker.generateUnitRanges(*CurrentUnit, File, AddrPool))
@@ -3028,7 +3030,7 @@ void DWARFLinker::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader,
OnCUDieLoaded(*CU);
- if (!LLVM_UNLIKELY(Options.Update))
+ if (!LLVM_UNLIKELY(Options.getUpdate()))
registerModuleReference(CUDie, ObjectContexts.back(), Loader,
OnCUDieLoaded);
}
@@ -3060,14 +3062,14 @@ Error DWARFLinker::link() {
if (!OptContext.File.Dwarf)
continue;
- if (Options.VerifyInputDWARF)
+ if (Options.getVerifyInputDWARF())
verifyInput(OptContext.File);
// Look for relocations that correspond to address map entries.
// there was findvalidrelocations previously ... probably we need to gather
// info here
- if (LLVM_LIKELY(!Options.Update) &&
+ if (LLVM_LIKELY(!Options.getUpdate()) &&
!OptContext.File.Addresses->hasValidRelocs()) {
if (Options.Verbose)
outs() << "No valid relocations found. Skipping.\n";
@@ -3142,10 +3144,11 @@ Error DWARFLinker::link() {
auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false);
std::string PCMFile = getPCMFile(CUDie, Options.ObjectPrefixMap);
- if (!CUDie || LLVM_UNLIKELY(Options.Update) ||
+ if (!CUDie || LLVM_UNLIKELY(Options.getUpdate()) ||
!isClangModuleRef(CUDie, PCMFile, Context, 0, true).first) {
Context.CompileUnits.push_back(std::make_unique<CompileUnit>(
- *CU, UniqueUnitID++, !Options.NoODR && !Options.Update, ""));
+ *CU, UniqueUnitID++, !Options.getNoODR() && !Options.getUpdate(),
+ ""));
}
}
@@ -3180,7 +3183,7 @@ Error DWARFLinker::link() {
// Note that this loop can not be merged with the previous one because
// cross-cu references require the ParentIdx to be setup for every CU in
// the object file before calling this.
- if (LLVM_UNLIKELY(Options.Update)) {
+ if (LLVM_UNLIKELY(Options.getUpdate())) {
for (auto &CurrentUnit : OptContext.CompileUnits)
CurrentUnit->markEverythingAsKept();
copyInvariantDebugSection(*OptContext.File.Dwarf);
@@ -3199,12 +3202,12 @@ Error DWARFLinker::link() {
// array again (in the same way findValidRelocsInDebugInfo() did). We
// need to reset the NextValidReloc index to the beginning.
if (OptContext.File.Addresses->hasValidRelocs() ||
- LLVM_UNLIKELY(Options.Update)) {
+ LLVM_UNLIKELY(Options.getUpdate())) {
SizeByObject[OptContext.File.FileName].Input =
getDebugInfoSize(*OptContext.File.Dwarf);
Expected<uint64_t> SizeOrErr =
DIECloner(*this, TheDwarfEmitter, OptContext.File, DIEAlloc,
- OptContext.CompileUnits, Options.Update, DebugStrPool,
+ OptContext.CompileUnits, Options.getUpdate(), DebugStrPool,
DebugLineStrPool, StringOffsetPool)
.cloneAllCompileUnits(*OptContext.File.Dwarf, OptContext.File,
OptContext.File.Dwarf->isLittleEndian());
@@ -3215,7 +3218,7 @@ Error DWARFLinker::link() {
SizeByObject[OptContext.File.FileName].Output = *SizeOrErr;
}
if ((TheDwarfEmitter != nullptr) && !OptContext.CompileUnits.empty() &&
- LLVM_LIKELY(!Options.Update))
+ LLVM_LIKELY(!Options.getUpdate()))
patchFrameInfoForObject(OptContext);
// Clean-up before starting working on the next object.
@@ -3383,7 +3386,7 @@ Error DWARFLinker::cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
assert(TheDwarfEmitter);
Expected<uint64_t> SizeOrErr =
DIECloner(*this, TheDwarfEmitter, Unit.File, DIEAlloc, CompileUnits,
- Options.Update, DebugStrPool, DebugLineStrPool,
+ Options.getUpdate(), DebugStrPool, DebugLineStrPool,
StringOffsetPool)
.cloneAllCompileUnits(*Unit.File.Dwarf, Unit.File,
Unit.File.Dwarf->isLittleEndian());
diff --git a/llvm/lib/DWARFLinker/Parallel/DIEAttributeCloner.cpp b/llvm/lib/DWARFLinker/Parallel/DIEAttributeCloner.cpp
index 67545ee03d15b..504112891eef1 100644
--- a/llvm/lib/DWARFLinker/Parallel/DIEAttributeCloner.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DIEAttributeCloner.cpp
@@ -143,7 +143,7 @@ bool DIEAttributeCloner::shouldSkipAttribute(
case dwarf::DW_AT_low_pc:
case dwarf::DW_AT_high_pc:
case dwarf::DW_AT_ranges:
- if (InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
+ if (InUnit.getGlobalData().getOptions().getUpdateIndexTablesOnly())
return false;
// Skip address attribute if we are in function scope and function does not
@@ -155,16 +155,16 @@ bool DIEAttributeCloner::shouldSkipAttribute(
// Thus instead of DW_FORM_rnglistx the DW_FORM_sec_offset is used.
// Since DW_AT_rnglists_base is used for only DW_FORM_rnglistx the
// DW_AT_rnglists_base is removed.
- return !InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
+ return !InUnit.getGlobalData().getOptions().getUpdateIndexTablesOnly();
case dwarf::DW_AT_loclists_base:
// In case !Update the .debug_addr table is not generated/preserved.
// Thus instead of DW_FORM_loclistx the DW_FORM_sec_offset is used.
// Since DW_AT_loclists_base is used for only DW_FORM_loclistx the
// DW_AT_loclists_base is removed.
- return !InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
+ return !InUnit.getGlobalData().getOptions().getUpdateIndexTablesOnly();
case dwarf::DW_AT_location:
case dwarf::DW_AT_frame_base:
- if (InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
+ if (InUnit.getGlobalData().getOptions().getUpdateIndexTablesOnly())
return false;
// When location expression contains an address: skip this attribute
@@ -418,7 +418,7 @@ size_t DIEAttributeCloner::cloneScalarAttr(
InputDieEntry->getTag() == dwarf::DW_TAG_constant))
AttrInfo.HasLiveAddress = true;
- if (InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly) {
+ if (InUnit.getGlobalData().getOptions().getUpdateIndexTablesOnly()) {
if (auto OptionalValue = Val.getAsUnsignedConstant())
Value = *OptionalValue;
else if (auto OptionalValue = Val.getAsSignedConstant())
@@ -655,7 +655,7 @@ size_t DIEAttributeCloner::cloneBlockAttr(
if (HasLocationExpressionAddress)
AttrInfo.HasLiveAddress =
VarAddressAdjustment.has_value() ||
- InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly;
+ InUnit.getGlobalData().getOptions().getUpdateIndexTablesOnly();
return FinalAttributeSize;
}
@@ -666,7 +666,7 @@ size_t DIEAttributeCloner::cloneAddressAttr(
if (AttrSpec.Attr == dwarf::DW_AT_low_pc)
AttrInfo.HasLiveAddress = true;
- if (InUnit.getGlobalData().getOptions().UpdateIndexTablesOnly)
+ if (InUnit.getGlobalData().getOptions().getUpdateIndexTablesOnly())
return Generator
.addScalarAttribute(AttrSpec.Attr, AttrSpec.Form, Val.getRawUValue())
.second;
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
index eb2f04174f1c4..424f8c4724654 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp
@@ -53,9 +53,9 @@ CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit,
Language = CUDie.getLanguage();
- if (!GlobalData.getOptions().NoODR && Language.has_value() &&
+ if (!GlobalData.getOptions().getNoODR() && Language.has_value() &&
isODRLanguage(*Language))
- NoODR = false;
+ setNoODR(false);
if (const char *CUName = CUDie.getName(DINameKind::ShortName))
UnitName = CUName;
@@ -114,7 +114,7 @@ bool CompileUnit::loadInputDIEs() {
// load input dies, resize Info structures array.
DieInfoArray.resize(getOrigUnit().getNumDIEs());
OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0);
- if (!NoODR)
+ if (!getNoODR())
TypeEntries.resize(getOrigUnit().getNumDIEs());
return true;
}
@@ -168,11 +168,12 @@ void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
break;
}
- if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly)
+ if (!isClangModule() &&
+ !getGlobalData().getOptions().getUpdateIndexTablesOnly())
ChildInfo.setTrackLiveness();
if ((!ChildInfo.getIsInAnonNamespaceScope() &&
- !ChildIsODRUnavailableFunctionScope && !NoODR))
+ !ChildIsODRUnavailableFunctionScope && !getNoODR()))
ChildInfo.setODRAvailable();
if (CurChild->hasChildren())
@@ -250,7 +251,7 @@ void CompileUnit::cleanupDataAfterClonning() {
FileNames.shrink_and_clear();
DieInfoArray = SmallVector<DIEInfo>();
OutDieOffsetArray = SmallVector<uint64_t>();
- TypeEntries = SmallVector<TypeEntry *>();
+ TypeEntries.assign(SmallVector<TypeEntry *>());
Dependencies.reset(nullptr);
StmtSeqListAttributes.clear();
getOrigUnit().clear();
@@ -556,7 +557,7 @@ void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
}
Error CompileUnit::cloneAndEmitDebugLocations() {
- if (getGlobalData().getOptions().UpdateIndexTablesOnly)
+ if (getGlobalData().getOptions().getUpdateIndexTablesOnly())
return Error::success();
if (getOrigUnit().getVersion() < 5) {
@@ -744,7 +745,7 @@ uint64_t CompileUnit::emitLocListFragment(
}
Error CompileUnit::emitDebugAddrSection() {
- if (GlobalData.getOptions().UpdateIndexTablesOnly)
+ if (GlobalData.getOptions().getUpdateIndexTablesOnly())
return Error::success();
if (getVersion() < 5)
@@ -786,7 +787,7 @@ Error CompileUnit::emitDebugAddrSection() {
}
Error CompileUnit::cloneAndEmitRanges() {
- if (getGlobalData().getOptions().UpdateIndexTablesOnly)
+ if (getGlobalData().getOptions().getUpdateIndexTablesOnly())
return Error::success();
// Build set of linked address ranges for unit function ranges.
@@ -1287,7 +1288,7 @@ void CompileUnit::cloneDieAttrExpression(
assert(RealSize == ULEBsize && "padding failed");
ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end());
- } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
+ } else if (!getGlobalData().getOptions().getUpdateIndexTablesOnly() &&
Op.getCode() == dwarf::DW_OP_addrx) {
if (std::optional<object::SectionedAddress> SA =
OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
@@ -1309,7 +1310,7 @@ void CompileUnit::cloneDieAttrExpression(
OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
} else
warn("cann't read DW_OP_addrx operand.");
- } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
+ } else if (!getGlobalData().getOptions().getUpdateIndexTablesOnly() &&
Op.getCode() == dwarf::DW_OP_constx) {
if (std::optional<object::SectionedAddress> SA =
OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
@@ -1689,7 +1690,7 @@ Error CompileUnit::cloneAndEmitLineTable(const Triple &TargetTriple) {
OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize;
// Set Line Table Rows.
- if (getGlobalData().getOptions().UpdateIndexTablesOnly) {
+ if (getGlobalData().getOptions().getUpdateIndexTablesOnly()) {
OutLineTable.Rows = InputLineTable->Rows;
// If all the line table contains is a DW_LNE_end_sequence, clear the line
// table rows, it will be inserted again in the DWARFStreamer.
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
index c8c1b8822aa64..bb5791be78d2d 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
@@ -10,6 +10,7 @@
#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H
#include "DWARFLinkerUnit.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/DWARFLinker/DWARFFile.h"
#include <limits>
#include <optional>
@@ -821,7 +822,11 @@ class alignas(8) CompileUnit : public DwarfUnit {
uint64_t HighPc = 0;
/// Flag indicating whether type de-duplication is forbidden.
- bool NoODR = true;
+ bool getNoODR() const { return !TypeEntries.getFlag(0); }
+ bool setNoODR(bool Value) {
+ TypeEntries.setFlag(0, !Value);
+ return Value;
+ }
/// Deterministic priority for type DIE allocation (lower wins).
uint64_t Priority = std::numeric_limits<uint64_t>::max();
@@ -855,7 +860,7 @@ class alignas(8) CompileUnit : public DwarfUnit {
/// DIE info indexed by DIE index.
SmallVector<DIEInfo> DieInfoArray;
SmallVector<uint64_t> OutDieOffsetArray;
- SmallVector<TypeEntry *> TypeEntries;
+ llvm::SmallVectorWithFlags<TypeEntry *> TypeEntries;
/// The list of accelerator records for this unit.
ArrayList<AccelInfo> AcceleratorRecords;
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h
index b65c5d809b1d1..36a060c56a425 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerGlobalData.h
@@ -11,6 +11,7 @@
#include "ModulePool.h"
#include "TypePool.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
#include "llvm/DWARFLinker/StringPool.h"
#include "llvm/Support/PerThreadBumpPtrAllocator.h"
@@ -37,23 +38,30 @@ struct DWARFLinkerOptions {
bool Statistics = false;
/// Verify the input DWARF.
- bool VerifyInputDWARF = false;
+ bool getVerifyInputDWARF() const { return AccelTables.getFlag(0); }
+ void setVerifyInputDWARF(bool Value) { AccelTables.setFlag(0, Value); }
/// Do not unique types according to ODR
- bool NoODR = false;
+ bool getNoODR() const { return AccelTables.getFlag(1); }
+ bool setNoODR(bool Value) {
+ AccelTables.setFlag(1, Value);
+ return Value;
+ }
/// Update index tables.
- bool UpdateIndexTablesOnly = false;
+ bool getUpdateIndexTablesOnly() const { return AccelTables.getFlag(2); }
+ void setUpdateIndexTablesOnly(bool Value) { AccelTables.setFlag(2, Value); }
/// Whether we want a static variable to force us to keep its enclosing
/// function.
- bool KeepFunctionForStatic = false;
+ bool getKeepFunctionForStatic() const { return AccelTables.getFlag(3); }
+ void setKeepFunctionForStatic(bool Value) { AccelTables.setFlag(3, Value); }
/// Number of threads.
unsigned Threads = 1;
/// The accelerator table kinds
- SmallVector<DWARFLinkerBase::AccelTableKind, 1> AccelTables;
+ llvm::SmallVectorWithFlags<DWARFLinkerBase::AccelTableKind, 1, 4> AccelTables;
/// Prepend path for the clang modules.
std::string PrependPath;
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
index f0fd044b09e76..3dbbc3bccb805 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
@@ -64,7 +64,7 @@ void DWARFLinkerImpl::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader,
OnCUDieLoaded(*CU);
// Register mofule reference.
- if (!GlobalData.getOptions().UpdateIndexTablesOnly)
+ if (!GlobalData.getOptions().getUpdateIndexTablesOnly())
ObjectContexts.back()->registerModuleReference(CUDie, Loader,
OnCUDieLoaded);
}
@@ -117,7 +117,7 @@ Error DWARFLinkerImpl::link() {
}
// Verify input DWARF if requested.
- if (GlobalData.getOptions().VerifyInputDWARF)
+ if (GlobalData.getOptions().getVerifyInputDWARF())
verifyInput(Context->InputDWARFFile);
if (!GlobalData.getTargetTriple())
@@ -165,7 +165,7 @@ Error DWARFLinkerImpl::link() {
CommonSections.setOutputFormat(GlobalFormat, GlobalEndianness);
- if (!GlobalData.Options.NoODR && Language.has_value()) {
+ if (!GlobalData.Options.getNoODR() && Language.has_value()) {
llvm::parallel::TaskGroup TGroup;
TGroup.spawn([&]() {
ArtificialTypeUnit = std::make_unique<TypeUnit>(
@@ -222,7 +222,7 @@ Error DWARFLinkerImpl::link() {
// Build the linker-wide CIE registry, then emit each context's
// .debug_frame in parallel. See CIERegistry for the ownership rules.
- if (!GlobalData.getOptions().UpdateIndexTablesOnly) {
+ if (!GlobalData.getOptions().getUpdateIndexTablesOnly()) {
LinkContext::CIERegistry CIEs;
for (std::unique_ptr<LinkContext> &Context : ObjectContexts)
if (Context->FrameScan)
@@ -282,9 +282,9 @@ Error DWARFLinkerImpl::validateAndUpdateOptions() {
}
// Do not do types deduplication in case --update.
- if (GlobalData.getOptions().UpdateIndexTablesOnly &&
- !GlobalData.Options.NoODR)
- GlobalData.Options.NoODR = true;
+ if (GlobalData.getOptions().getUpdateIndexTablesOnly() &&
+ !GlobalData.Options.getNoODR())
+ GlobalData.Options.setNoODR(true);
return Error::success();
}
@@ -487,7 +487,7 @@ Error DWARFLinkerImpl::LinkContext::loadClangModule(
}
Error DWARFLinkerImpl::LinkContext::link(TypeUnit *ArtificialTypeUnit) {
- InterCUProcessingStarted = false;
+ setInterCUProcessingStarted(false);
if (!InputDWARFFile.Dwarf)
return Error::success();
@@ -506,7 +506,7 @@ Error DWARFLinkerImpl::LinkContext::link(TypeUnit *ArtificialTypeUnit) {
// Check for live relocations. If there is no any live relocation then we
// can skip entire object file.
- if (!GlobalData.getOptions().UpdateIndexTablesOnly &&
+ if (!GlobalData.getOptions().getUpdateIndexTablesOnly() &&
!InputDWARFFile.Addresses->hasValidRelocs()) {
if (GlobalData.getOptions().Verbose)
outs() << "No valid relocations found. Skipping.\n";
@@ -526,7 +526,7 @@ Error DWARFLinkerImpl::LinkContext::link(TypeUnit *ArtificialTypeUnit) {
// The !isClangModuleRef condition effectively skips over fully resolved
// skeleton units.
- if (!CUDie || GlobalData.getOptions().UpdateIndexTablesOnly ||
+ if (!CUDie || GlobalData.getOptions().getUpdateIndexTablesOnly() ||
!isClangModuleRef(CUDie, PCMFile, 0, true).first) {
CompileUnits.emplace_back(std::make_unique<CompileUnit>(
GlobalData, *OrigCU, UniqueUnitID.fetch_add(1), "", InputDWARFFile,
@@ -550,7 +550,7 @@ Error DWARFLinkerImpl::LinkContext::link(TypeUnit *ArtificialTypeUnit) {
// Link all inter-connected units.
if (HasNewInterconnectedCUs) {
- InterCUProcessingStarted = true;
+ setInterCUProcessingStarted(true);
if (Error Err = finiteLoop([&]() -> Expected<bool> {
HasNewInterconnectedCUs = false;
@@ -616,7 +616,7 @@ Error DWARFLinkerImpl::LinkContext::link(TypeUnit *ArtificialTypeUnit) {
});
}
- if (GlobalData.getOptions().UpdateIndexTablesOnly) {
+ if (GlobalData.getOptions().getUpdateIndexTablesOnly()) {
// Emit Invariant sections.
if (Error Err = emitInvariantSections())
@@ -629,7 +629,7 @@ Error DWARFLinkerImpl::LinkContext::link(TypeUnit *ArtificialTypeUnit) {
void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
CompileUnit &CU, TypeUnit *ArtificialTypeUnit,
enum CompileUnit::Stage DoUntilStage) {
- if (InterCUProcessingStarted != CU.isInterconnectedCU())
+ if (getInterCUProcessingStarted() != CU.isInterconnectedCU())
return;
if (Error Err = finiteLoop([&]() -> Expected<bool> {
@@ -656,7 +656,7 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
// Runs concurrently, so it must stay a no-op: it may only be
// entered when the serial pass in addObjectFile() has already
// populated the module map.
- if (!GlobalData.getOptions().UpdateIndexTablesOnly &&
+ if (!GlobalData.getOptions().getUpdateIndexTablesOnly() &&
registerModuleReference(
CU.getOrigUnit().getUnitDIE(), nullptr,
[](const DWARFUnit &) {}, 0))
@@ -669,8 +669,8 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
case CompileUnit::Stage::Loaded: {
// Mark all the DIEs that need to be present in the generated output.
// If ODR requested, build type names.
- if (!CU.resolveDependenciesAndMarkLiveness(InterCUProcessingStarted,
- HasNewInterconnectedCUs)) {
+ if (!CU.resolveDependenciesAndMarkLiveness(
+ getInterCUProcessingStarted(), HasNewInterconnectedCUs)) {
assert(HasNewInterconnectedCUs &&
"Flag indicating new inter-connections is not set");
return false;
@@ -680,7 +680,7 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
} break;
case CompileUnit::Stage::LivenessAnalysisDone: {
- if (InterCUProcessingStarted) {
+ if (getInterCUProcessingStarted()) {
if (CU.updateDependenciesCompleteness())
HasNewGlobalDependency = true;
return false;
@@ -710,7 +710,7 @@ void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
case CompileUnit::Stage::TypeNamesAssigned:
// Clone input compile unit.
if (CU.isClangModule() ||
- GlobalData.getOptions().UpdateIndexTablesOnly ||
+ GlobalData.getOptions().getUpdateIndexTablesOnly() ||
CU.getContainingFile().Addresses->hasValidRelocs()) {
if (Error Err = CU.cloneAndEmit(GlobalData.getTargetTriple(),
ArtificialTypeUnit))
@@ -779,7 +779,7 @@ Error DWARFLinkerImpl::LinkContext::emitInvariantSections() {
}
Error DWARFLinkerImpl::LinkContext::scanFrameData() {
- if (GlobalData.getOptions().UpdateIndexTablesOnly)
+ if (GlobalData.getOptions().getUpdateIndexTablesOnly())
return Error::success();
if (!GlobalData.getTargetTriple().has_value())
return Error::success();
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
index b7286bbb82a28..2c3337e3d01c6 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.h
@@ -15,6 +15,7 @@
#include "StringEntryToDwarfStringPoolEntryMap.h"
#include "llvm/ADT/AddressRanges.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/AccelTable.h"
#include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
#include "llvm/DWARFLinker/StringPool.h"
@@ -68,20 +69,20 @@ class DWARFLinkerImpl : public DWARFLinker {
/// Verify the input DWARF.
void setVerifyInputDWARF(bool Verify) override {
- GlobalData.Options.VerifyInputDWARF = Verify;
+ GlobalData.Options.setVerifyInputDWARF(Verify);
}
/// Do not unique types according to ODR.
- void setNoODR(bool NoODR) override { GlobalData.Options.NoODR = NoODR; }
+ void setNoODR(bool NoODR) override { GlobalData.Options.setNoODR(NoODR); }
/// Update index tables only(do not modify rest of DWARF).
void setUpdateIndexTablesOnly(bool UpdateIndexTablesOnly) override {
- GlobalData.Options.UpdateIndexTablesOnly = UpdateIndexTablesOnly;
+ GlobalData.Options.setUpdateIndexTablesOnly(UpdateIndexTablesOnly);
}
/// Set to keep the enclosing function for a static variable.
void setKeepFunctionForStatic(bool KeepFunctionForStatic) override {
- GlobalData.Options.KeepFunctionForStatic = KeepFunctionForStatic;
+ GlobalData.Options.setKeepFunctionForStatic(KeepFunctionForStatic);
}
/// Use specified number of threads for parallel files linking.
@@ -165,7 +166,7 @@ class DWARFLinkerImpl : public DWARFLinker {
UnitListTy CompileUnits;
/// Set of Compile Units for modules.
- UnitListTy ModulesCompileUnits;
+ llvm::SmallVectorWithFlagsFor<UnitListTy, 1> ModulesCompileUnits;
/// Index of this object file in the link order (used for deterministic
/// type DIE allocation).
@@ -176,7 +177,12 @@ class DWARFLinkerImpl : public DWARFLinker {
/// Flag indicating that all inter-connected units are loaded
/// and the dwarf linking process for these units is started.
- bool InterCUProcessingStarted = false;
+ bool getInterCUProcessingStarted() const {
+ return ModulesCompileUnits.getFlag(0);
+ }
+ void setInterCUProcessingStarted(bool Value) {
+ ModulesCompileUnits.setFlag(0, Value);
+ }
StringMap<uint64_t> &ClangModules;
diff --git a/llvm/lib/DWARFLinker/Parallel/DependencyTracker.cpp b/llvm/lib/DWARFLinker/Parallel/DependencyTracker.cpp
index 669ea2ceb16c9..99e51508c2221 100644
--- a/llvm/lib/DWARFLinker/Parallel/DependencyTracker.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DependencyTracker.cpp
@@ -127,9 +127,9 @@ bool DependencyTracker::resolveDependenciesAndMarkLiveness(
// be resolved is reset to its loaded stage and marked again from scratch, so
// no reference recorded under one resolution mode survives into another.
assert((SubtreeDependencyRefs.empty() ||
- InterCUProcessingWasStarted == InterCUProcessingStarted) &&
+ getInterCUProcessingWasStarted() == InterCUProcessingStarted) &&
"recorded subtrees would be walked in a different resolution mode");
- InterCUProcessingWasStarted = InterCUProcessingStarted;
+ setInterCUProcessingWasStarted(InterCUProcessingStarted);
// Search for live root DIEs.
CompileUnit::DIEInfo &CUInfo = CU.getDIEInfo(CU.getDebugInfoEntry(0));
@@ -326,7 +326,7 @@ void DependencyTracker::materializeSubtreeSummaries() {
std::atomic<bool> HasNewInterconnectedCUs = false;
[[maybe_unused]] bool Res = markDIEEntryAsKeptRec(
Ref.Action, Ref.ReferencedBy, Ref.Subtree,
- InterCUProcessingWasStarted, HasNewInterconnectedCUs,
+ getInterCUProcessingWasStarted(), HasNewInterconnectedCUs,
TreeWalkKindTy::RecordSubtreeDeps);
assert(Res && !HasNewInterconnectedCUs && "record-deps-only walk failed");
}
@@ -998,7 +998,7 @@ bool DependencyTracker::isLiveVariableEntry(const UnitEntryPairTy &Entry,
return false;
if (!IsLiveParent && Info.getIsInFunctionScope() &&
- !Entry.CU->getGlobalData().getOptions().KeepFunctionForStatic)
+ !Entry.CU->getGlobalData().getOptions().getKeepFunctionForStatic())
return false;
}
}
diff --git a/llvm/lib/DWARFLinker/Parallel/DependencyTracker.h b/llvm/lib/DWARFLinker/Parallel/DependencyTracker.h
index dbf67cce3365c..83619ddcb4f1d 100644
--- a/llvm/lib/DWARFLinker/Parallel/DependencyTracker.h
+++ b/llvm/lib/DWARFLinker/Parallel/DependencyTracker.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace llvm {
class DWARFDebugInfoEntry;
@@ -391,7 +392,7 @@ class DependencyTracker {
DenseMap<SubtreeDependenciesKeyTy, SubtreeDependenciesTy> SubtreeSummaries;
/// Roots referencing an already-marked subtree.
- SmallVector<SubtreeDependencyRefTy> SubtreeDependencyRefs;
+ llvm::SmallVectorWithFlags<SubtreeDependencyRefTy> SubtreeDependencyRefs;
/// Number of leading SubtreeDependencyRefs whose subtree is summarized.
size_t MaterializedRefs = 0;
@@ -403,7 +404,12 @@ class DependencyTracker {
/// Whether inter-unit references could be resolved during marking. Reused
/// when the recorded subtrees are walked, which happens outside of marking.
- bool InterCUProcessingWasStarted = false;
+ bool getInterCUProcessingWasStarted() const {
+ return SubtreeDependencyRefs.getFlag(0);
+ }
+ void setInterCUProcessingWasStarted(bool Value) {
+ SubtreeDependencyRefs.setFlag(0, Value);
+ }
};
} // end of namespace parallel
diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index b9aaa3146c9cc..60a0d3cf9cb91 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -8,6 +8,7 @@
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
@@ -126,11 +127,12 @@ class TypeStreamMerger {
}
bool hasTypeStream() const {
- return (UseGlobalHashes) ? (!!DestGlobalTypeStream) : (!!DestTypeStream);
+ return (getUseGlobalHashes()) ? (!!DestGlobalTypeStream)
+ : (!!DestTypeStream);
}
bool hasIdStream() const {
- return (UseGlobalHashes) ? (!!DestGlobalIdStream) : (!!DestIdStream);
+ return (getUseGlobalHashes()) ? (!!DestGlobalIdStream) : (!!DestIdStream);
}
ArrayRef<uint8_t> remapIndices(const CVType &OriginalType,
@@ -169,9 +171,11 @@ class TypeStreamMerger {
std::optional<Error> LastError;
- bool UseGlobalHashes = false;
+ bool getUseGlobalHashes() const { return RemapStorage.getFlag(0); }
+ void setUseGlobalHashes(bool Value) { RemapStorage.setFlag(0, Value); }
- bool IsSecondPass = false;
+ bool getIsSecondPass() const { return RemapStorage.getFlag(1); }
+ void setIsSecondPass(bool Value) { RemapStorage.setFlag(1, Value); }
unsigned NumBadIndices = 0;
@@ -195,7 +199,7 @@ class TypeStreamMerger {
/// Temporary storage that we use to copy a record's data while re-writing
/// its type indices.
- SmallVector<uint8_t, 256> RemapStorage;
+ llvm::SmallVectorWithFlags<uint8_t, 256, 2> RemapStorage;
std::optional<PCHMergerInfo> PCHInfo;
};
@@ -205,7 +209,7 @@ class TypeStreamMerger {
const TypeIndex TypeStreamMerger::Untranslated(SimpleTypeKind::NotTranslated);
void TypeStreamMerger::addMapping(TypeIndex Idx) {
- if (!IsSecondPass) {
+ if (!getIsSecondPass()) {
assert(IndexMap.size() == slotForIndex(CurIndex) &&
"visitKnownRecord should add one index map entry");
IndexMap.push_back(Idx);
@@ -221,7 +225,7 @@ bool TypeStreamMerger::remapIndexFallback(TypeIndex &Idx,
// If this is the second pass and this index isn't in the map, then it points
// outside the current type stream, and this is a corrupt record.
- if (IsSecondPass && MapPos >= Map.size()) {
+ if (getIsSecondPass() && MapPos >= Map.size()) {
// FIXME: Print a more useful error. We can give the current record and the
// index that we think its pointing to.
if (LastError)
@@ -242,7 +246,7 @@ bool TypeStreamMerger::remapIndexFallback(TypeIndex &Idx,
Error TypeStreamMerger::mergeTypeRecords(MergingTypeTableBuilder &Dest,
const CVTypeArray &Types) {
DestTypeStream = &Dest;
- UseGlobalHashes = false;
+ setUseGlobalHashes(false);
return doit(Types);
}
@@ -252,7 +256,7 @@ Error TypeStreamMerger::mergeIdRecords(MergingTypeTableBuilder &Dest,
const CVTypeArray &Ids) {
DestIdStream = &Dest;
TypeLookup = TypeSourceToDest;
- UseGlobalHashes = false;
+ setUseGlobalHashes(false);
return doit(Ids);
}
@@ -262,7 +266,7 @@ Error TypeStreamMerger::mergeTypesAndIds(
const CVTypeArray &IdsAndTypes, std::optional<PCHMergerInfo> &PCHInfo) {
DestIdStream = &DestIds;
DestTypeStream = &DestTypes;
- UseGlobalHashes = false;
+ setUseGlobalHashes(false);
auto Err = doit(IdsAndTypes);
PCHInfo = this->PCHInfo;
return Err;
@@ -274,7 +278,7 @@ Error TypeStreamMerger::mergeTypeRecords(
ArrayRef<GloballyHashedType> Hashes,
std::optional<PCHMergerInfo> &PCHInfo) {
DestGlobalTypeStream = &Dest;
- UseGlobalHashes = true;
+ setUseGlobalHashes(true);
GlobalHashes = Hashes;
auto Err = doit(Types);
PCHInfo = this->PCHInfo;
@@ -287,7 +291,7 @@ Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest,
ArrayRef<GloballyHashedType> Hashes) {
DestGlobalIdStream = &Dest;
TypeLookup = TypeSourceToDest;
- UseGlobalHashes = true;
+ setUseGlobalHashes(true);
GlobalHashes = Hashes;
return doit(Ids);
@@ -299,7 +303,7 @@ Error TypeStreamMerger::mergeTypesAndIds(
std::optional<PCHMergerInfo> &PCHInfo) {
DestGlobalIdStream = &DestIds;
DestGlobalTypeStream = &DestTypes;
- UseGlobalHashes = true;
+ setUseGlobalHashes(true);
GlobalHashes = Hashes;
auto Err = doit(IdsAndTypes);
PCHInfo = this->PCHInfo;
@@ -319,7 +323,7 @@ Error TypeStreamMerger::doit(const CVTypeArray &Types) {
// efficient. MASM type streams are usually very small.
while (!LastError && NumBadIndices > 0) {
unsigned BadIndicesRemaining = NumBadIndices;
- IsSecondPass = true;
+ setIsSecondPass(true);
NumBadIndices = 0;
CurIndex = TypeIndex(TypeIndex::FirstNonSimpleIndex);
@@ -361,7 +365,7 @@ Error TypeStreamMerger::remapType(const CVType &Type) {
};
unsigned AlignedSize = alignTo(Type.RecordData.size(), 4);
- if (LLVM_LIKELY(UseGlobalHashes)) {
+ if (LLVM_LIKELY(getUseGlobalHashes())) {
GlobalTypeTableBuilder &Dest =
isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
@@ -379,7 +383,7 @@ Error TypeStreamMerger::remapType(const CVType &Type) {
addMapping(DestIdx);
++CurIndex;
- assert((IsSecondPass || IndexMap.size() == slotForIndex(CurIndex)) &&
+ assert((getIsSecondPass() || IndexMap.size() == slotForIndex(CurIndex)) &&
"visitKnownRecord should add one index map entry");
return Error::success();
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index 91c208eea9738..7b67ad54480c5 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -46,7 +46,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
unsigned IndLevel = 0;
for (const auto &Macros : MacroLists) {
OS << formatv("{0:x8}:\n", Macros.Offset);
- if (Macros.IsDebugMacro)
+ if (Macros.getIsDebugMacro())
Macros.Header.dumpMacroHeader(OS);
for (const Entry &E : Macros.Macros) {
// There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
@@ -58,7 +58,7 @@ 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)
+ if (Macros.getIsDebugMacro())
WithColor(OS, HighlightColor::Macro).get()
<< (Macros.Header.Version < 5 ? GnuMacroString(E.Type)
: MacroString(E.Type));
@@ -130,7 +130,7 @@ Error DWARFDebugMacro::parseImpl(
MacroLists.emplace_back();
M = &MacroLists.back();
M->Offset = Offset;
- M->IsDebugMacro = IsMacro;
+ M->setIsDebugMacro(IsMacro);
if (IsMacro) {
auto Err = M->Header.parseMacroHeader(Data, &Offset);
if (Err)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
index bc9e888b0bd7f..72b5c0fd2f0a2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
@@ -100,7 +100,7 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
DIDumpOptions DumpOpts, const DWARFExpression *Expr,
DWARFUnit *U) {
if (Op->isError()) {
- if (!DumpOpts.PrintRegisterOnly)
+ if (!DumpOpts.printRegisterOnly())
OS << "<decoding error>";
return false;
}
@@ -111,7 +111,7 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
// This lets clients print annotations like "i = 0" when the location is
// a constant (e.g. DW_OP_constu/consts ... DW_OP_stack_value).
// We continue to suppress all other non-register ops in this mode.
- if (DumpOpts.PrintRegisterOnly) {
+ if (DumpOpts.printRegisterOnly()) {
// First, try pretty-printing registers (existing behavior below also does
// this, but we need to short-circuit here to avoid printing opcode names).
if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
@@ -145,7 +145,7 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
return true; // suppress other opcodes silently in register-only mode
}
- if (!DumpOpts.PrintRegisterOnly) {
+ if (!DumpOpts.printRegisterOnly()) {
StringRef Name = OperationEncodingString(Op->getCode());
assert(!Name.empty() && "DW_OP has no name!");
OS << Name;
@@ -167,7 +167,7 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
Op->getRawOperands()))
return true;
- if (!DumpOpts.PrintRegisterOnly) {
+ if (!DumpOpts.printRegisterOnly()) {
for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
++Operand) {
unsigned Size = Op->getDescription().Op[Operand];
@@ -224,14 +224,14 @@ void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
for (auto &Op : *E) {
DumpOpts.IsEH = IsEH;
- if (!printOp(&Op, OS, DumpOpts, E, U) && !DumpOpts.PrintRegisterOnly) {
+ if (!printOp(&Op, OS, DumpOpts, E, U) && !DumpOpts.printRegisterOnly()) {
uint64_t FailOffset = Op.getEndOffset();
while (FailOffset < E->getData().size())
OS << formatv(" {0:x-2}",
static_cast<uint8_t>(E->getData()[FailOffset++]));
return;
}
- if (!DumpOpts.PrintRegisterOnly) {
+ if (!DumpOpts.printRegisterOnly()) {
if (Op.getCode() == DW_OP_entry_value ||
Op.getCode() == DW_OP_GNU_entry_value) {
OS << "(";
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 6b8eed4e4266b..9ad5f9e0de374 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -1207,7 +1207,7 @@ DWARFVerifier::DWARFVerifier(raw_ostream &S, DWARFContext &D,
: OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)), IsObjectFile(false),
IsMachOObject(false) {
ErrorCategory.ShowDetail(this->DumpOpts.Verbose ||
- !this->DumpOpts.ShowAggregateErrors);
+ !this->DumpOpts.showAggregateErrors());
if (const auto *F = DCtx.getDWARFObj().getFile()) {
IsObjectFile = F->isRelocatableObject();
IsMachOObject = F->isMachO();
@@ -2389,7 +2389,7 @@ void OutputCategoryAggregator::EnumerateDetailedResultsFor(
}
void DWARFVerifier::summarize() {
- if (DumpOpts.ShowAggregateErrors && ErrorCategory.GetNumCategories()) {
+ if (DumpOpts.showAggregateErrors() && ErrorCategory.GetNumCategories()) {
error() << "Aggregated error counts:\n";
ErrorCategory.EnumerateResults([&](StringRef s, unsigned count) {
error() << formatv("{0} occurred {1} time(s).\n", s, count);
diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
index eb3833dfdc9f2..5bc7b02755be8 100644
--- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -60,14 +60,14 @@ void JITEventListener::anchor() {}
void ObjectCache::anchor() {}
void ExecutionEngine::Init(std::unique_ptr<Module> M) {
- CompilingLazily = false;
- GVCompilationDisabled = false;
- SymbolSearchingDisabled = false;
+ setCompilingLazily(false);
+ setGVCompilationDisabled(false);
+ setSymbolSearchingDisabled(false);
// IR module verification is enabled by default in debug builds, and disabled
// by default in release builds.
#ifndef NDEBUG
- VerifyModules = true;
+ setVerifyModulesFlag(true);
#else
VerifyModules = false;
#endif
@@ -474,7 +474,7 @@ EngineBuilder::EngineBuilder(std::unique_ptr<Module> M)
// IR module verification is enabled by default in debug builds, and disabled
// by default in release builds.
#ifndef NDEBUG
- VerifyModules = true;
+ setVerifyModulesFlag(true);
#else
VerifyModules = false;
#endif
@@ -538,7 +538,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
std::move(Resolver), std::move(TheTM));
if (EE) {
- EE->setVerifyModules(VerifyModules);
+ EE->setVerifyModules(getVerifyModulesFlag());
return EE;
}
}
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp
index cf662afe24fe6..0fe065f229986 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp
@@ -865,7 +865,7 @@ Expected<LibraryDepsInfo> parseELF(const object::ELFFile<ELFT> &Elf) {
case ELF::DT_FLAGS_1:
// Check if this is not a pie executable.
if (Dyn.d_un.d_val & ELF::DF_1_PIE)
- Deps.isPIE = true;
+ Deps.setIsPIE(true);
break;
// (Dyn.d_tag == ELF::DT_NULL) continue;
// (Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER)
@@ -1008,7 +1008,7 @@ void LibraryScanner::handleLibrary(StringRef FilePath, PathType K, int level) {
dbgs() << " : " << r << "\n";
});
- if (Deps.isPIE && level == 0) {
+ if (Deps.getIsPIE() && level == 0) {
LLVM_DEBUG(dbgs() << " Skipped PIE executable at top level: " << FilePath
<< "\n";);
diff --git a/llvm/lib/ExecutionEngine/TargetSelect.cpp b/llvm/lib/ExecutionEngine/TargetSelect.cpp
index bce90fc33d64f..a6020f7ad7f2c 100644
--- a/llvm/lib/ExecutionEngine/TargetSelect.cpp
+++ b/llvm/lib/ExecutionEngine/TargetSelect.cpp
@@ -37,9 +37,8 @@ TargetMachine *EngineBuilder::selectTarget() {
/// selectTarget - Pick a target either via -march or by guessing the native
/// arch. Add any CPU features specified via -mcpu or -mattr.
TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
- StringRef MArch,
- StringRef MCPU,
- const SmallVectorImpl<std::string>& MAttrs) {
+ StringRef MArch, StringRef MCPU,
+ ArrayRef<std::string> MAttrs) {
Triple TheTriple(TargetTriple);
if (TheTriple.getTriple().empty())
TheTriple.setTriple(sys::getProcessTriple());
@@ -87,7 +86,7 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
TargetMachine *Target = TheTarget->createTargetMachine(
TheTriple, MCPU, FeaturesStr, Options, RelocModel, CMModel, OptLevel,
/*JIT=*/true);
- Target->Options.EmulatedTLS = EmulatedTLS;
+ Target->Options.EmulatedTLS = getEmulatedTLSFlag();
assert(Target && "Could not allocate target machine!");
return Target;
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index 732b608362879..80c146fe96c13 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -1025,7 +1025,7 @@ void OpenMPIRBuilder::finalize(Function *Fn) {
if (OI->PostOutlineCB)
OI->PostOutlineCB(*OutlinedFn);
- if (OI->FixUpNonEntryAllocas)
+ if (OI->getFixUpNonEntryAllocas())
hoistNonEntryAllocasToEntryBlock(OutlinedFn);
}
@@ -1076,10 +1076,10 @@ void OpenMPIRBuilder::finalize(Function *Fn) {
emitUsed("llvm.compiler.used", LLVMCompilerUsed);
}
- IsFinalized = true;
+ setIsFinalized(true);
}
-bool OpenMPIRBuilder::isFinalized() { return IsFinalized; }
+bool OpenMPIRBuilder::isFinalized() { return getIsFinalized(); }
void OpenMPIRBuilder::registerDeclareTargetGlobalReplacement(
GlobalValue *Original, GlobalValue *Replacement) {
@@ -2113,7 +2113,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createParallel(
};
}
- OI->FixUpNonEntryAllocas = true;
+ OI->setFixUpNonEntryAllocas(true);
OI->OuterAllocBB = OuterAllocaBlock;
OI->EntryBB = PRegEntryBB;
OI->ExitBB = PRegExitBB;
@@ -11772,7 +11772,7 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
Value *OldValue = nullptr;
Value *SuccessOrFail = nullptr;
- if (!IsInteger && HandleFPNegZero) {
+ if (!IsInteger && getHandleFPNegZeroFlag()) {
// IEEE 754 special cases for cmpxchg (which is bitwise):
// 1. -0.0 == +0.0 but they have different bit patterns.
// 2. NaN != NaN but identical NaN bit patterns would match.
@@ -11966,7 +11966,7 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
// For the HandleFPNegZero path, handle V.Var and R.Var using the
// pre-computed OldValue and SuccessOrFail.
- if (HandleFPNegZero && !IsInteger) {
+ if (getHandleFPNegZeroFlag() && !IsInteger) {
if (V.Var) {
assert(OldValue->getType() == V.ElemTy &&
"OldValue and V must be of same type");
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 1cbcfb195764b..9062069c5bf2e 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -25,6 +25,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -2986,12 +2987,14 @@ class AssemblyWriter {
SlotTracker &Machine;
TypePrinting TypePrinter;
AssemblyAnnotationWriter *AnnotationWriter = nullptr;
- bool IsForDebug;
- bool ShouldPreserveUseListOrder;
+ bool getIsForDebug() const { return SSNs.getFlag(0); }
+ void setIsForDebug(bool Value) { SSNs.setFlag(0, Value); }
+ bool getShouldPreserveUseListOrder() const { return SSNs.getFlag(1); }
+ void setShouldPreserveUseListOrder(bool Value) { SSNs.setFlag(1, Value); }
UseListOrderMap UseListOrders;
SmallVector<StringRef, 8> MDNames;
/// Synchronization scope names registered with LLVMContext.
- SmallVector<StringRef, 8> SSNs;
+ llvm::SmallVectorWithFlags<StringRef, 8, 2> SSNs;
DenseMap<const GlobalValueSummary *, GlobalValue::GUID> SummaryToGUIDMap;
public:
@@ -3089,17 +3092,19 @@ AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
const Module *M, AssemblyAnnotationWriter *AAW,
bool IsForDebug, bool ShouldPreserveUseListOrder)
: Out(o), TheModule(M), Machine(Mac), TypePrinter(M), AnnotationWriter(AAW),
- IsForDebug(IsForDebug),
- ShouldPreserveUseListOrder(
- PreserveAssemblyUseListOrder.getNumOccurrences()
- ? PreserveAssemblyUseListOrder
- : ShouldPreserveUseListOrder) {}
+ SSNs(decltype(this->SSNs)::withFlags(
+ unsigned(IsForDebug) |
+ (unsigned(bool(PreserveAssemblyUseListOrder.getNumOccurrences()
+ ? PreserveAssemblyUseListOrder
+ : ShouldPreserveUseListOrder))
+ << 1))) {}
AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
const ModuleSummaryIndex *Index, bool IsForDebug)
: Out(o), TheIndex(Index), Machine(Mac), TypePrinter(/*Module=*/nullptr),
- IsForDebug(IsForDebug),
- ShouldPreserveUseListOrder(PreserveAssemblyUseListOrder) {}
+ SSNs(decltype(this->SSNs)::withFlags(
+ unsigned(IsForDebug) |
+ (unsigned(bool(PreserveAssemblyUseListOrder)) << 1))) {}
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
if (!Operand) {
@@ -3117,8 +3122,11 @@ void AssemblyWriter::writeSyncScope(const LLVMContext &Context,
break;
}
default: {
- if (SSNs.empty())
- Context.getSyncScopeNames(SSNs);
+ if (SSNs.empty()) {
+ SmallVector<StringRef, 8> Names;
+ Context.getSyncScopeNames(Names);
+ SSNs.assign(std::move(Names));
+ }
Out << " syncscope(\"";
printEscapedString(SSNs[SSID], Out);
@@ -3205,7 +3213,7 @@ void AssemblyWriter::writeOperandBundles(const CallBase *Call) {
void AssemblyWriter::printModule(const Module *M) {
Machine.initializeIfNeeded();
- if (ShouldPreserveUseListOrder)
+ if (getShouldPreserveUseListOrder())
UseListOrders = predictUseListOrder(M);
if (!M->getModuleIdentifier().empty() &&
@@ -4296,7 +4304,7 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << '(';
// Loop over the arguments, printing them...
- if (F->isDeclaration() && !IsForDebug) {
+ if (F->isDeclaration() && !getIsForDebug()) {
// We're only interested in the type here - don't print argument names.
ListSeparator LS;
for (unsigned I = 0, E = FT->getNumParams(); I != E; ++I) {
@@ -5097,8 +5105,11 @@ void AssemblyWriter::printMetadataAttachments(
if (MDs.empty())
return;
- if (MDNames.empty())
- MDs[0].second->getContext().getMDKindNames(MDNames);
+ if (MDNames.empty()) {
+ SmallVector<StringRef, 8> Names;
+ MDs[0].second->getContext().getMDKindNames(Names);
+ MDNames.assign(std::move(Names));
+ }
auto WriterCtx = getContext();
for (const auto &I : MDs) {
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 37791652a4375..7baeb89de176e 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -24,8 +24,8 @@ using namespace llvm;
using namespace llvm::dwarf;
DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)
- : M(m), VMContext(M.getContext()), CUNode(CU),
- AllowUnresolvedNodes(AllowUnresolvedNodes) {
+ : M(m), VMContext(M.getContext()), CUNode(CU) {
+ UnresolvedNodes.setFlag(0, AllowUnresolvedNodes);
if (CUNode) {
if (const auto &ETs = CUNode->getEnumTypes())
EnumTypes.assign(ETs.begin(), ETs.end());
@@ -46,7 +46,7 @@ void DIBuilder::trackIfUnresolved(MDNode *N) {
if (N->isResolved())
return;
- assert(AllowUnresolvedNodes && "Cannot handle unresolved nodes");
+ assert(UnresolvedNodes.getFlag(0) && "Cannot handle unresolved nodes");
UnresolvedNodes.emplace_back(N);
}
@@ -72,7 +72,7 @@ void DIBuilder::finalizeSubprogram(DISubprogram *SP) {
void DIBuilder::finalize() {
if (!CUNode) {
- assert(!AllowUnresolvedNodes &&
+ assert(!UnresolvedNodes.getFlag(0) &&
"creating type nodes without a CU is not supported");
return;
}
@@ -131,7 +131,7 @@ void DIBuilder::finalize() {
UnresolvedNodes.clear();
// Can't handle unresolved nodes anymore.
- AllowUnresolvedNodes = false;
+ UnresolvedNodes.setFlag(0, false);
}
/// If N is compile unit return NULL otherwise return N.
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index 82b33887b81f2..05c4ee5cd1cb2 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -207,8 +207,6 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
delete static_cast<StructLayoutMap *>(LayoutMap);
LayoutMap = nullptr;
StringRepresentation = Other.StringRepresentation;
- BigEndian = Other.BigEndian;
- VectorsAreElementAligned = Other.VectorsAreElementAligned;
AllocaAddrSpace = Other.AllocaAddrSpace;
ProgramAddrSpace = Other.ProgramAddrSpace;
DefaultGlobalsAddrSpace = Other.DefaultGlobalsAddrSpace;
@@ -228,9 +226,7 @@ DataLayout &DataLayout::operator=(const DataLayout &Other) {
bool DataLayout::operator==(const DataLayout &Other) const {
// NOTE: StringRepresentation might differ, it is not canonicalized.
- return BigEndian == Other.BigEndian &&
- VectorsAreElementAligned == Other.VectorsAreElementAligned &&
- AllocaAddrSpace == Other.AllocaAddrSpace &&
+ return AllocaAddrSpace == Other.AllocaAddrSpace &&
ProgramAddrSpace == Other.ProgramAddrSpace &&
DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
StackNaturalAlign == Other.StackNaturalAlign &&
@@ -551,7 +547,7 @@ Error DataLayout::parseSpecification(
}
if (Spec == "ve") {
- VectorsAreElementAligned = true;
+ LegalIntWidths.setFlag(1, true);
return Error::success();
}
@@ -579,7 +575,7 @@ Error DataLayout::parseSpecification(
if (!Rest.empty())
return createStringError(
"malformed specification, must be just 'e' or 'E'");
- BigEndian = Specifier == 'E';
+ LegalIntWidths.setFlag(0, Specifier == 'E');
break;
case 'n': // Native integer types.
// n<size>[:<size>]...
diff --git a/llvm/lib/IR/DroppedVariableStats.cpp b/llvm/lib/IR/DroppedVariableStats.cpp
index b8c0dd6e7b1dc..456367c6aaa07 100644
--- a/llvm/lib/IR/DroppedVariableStats.cpp
+++ b/llvm/lib/IR/DroppedVariableStats.cpp
@@ -19,7 +19,8 @@
using namespace llvm;
DroppedVariableStats::DroppedVariableStats(bool DroppedVarStatsEnabled)
- : DroppedVariableStatsEnabled(DroppedVarStatsEnabled) {
+ : InlinedAts(decltype(this->InlinedAts)::withFlags(
+ unsigned(DroppedVarStatsEnabled))) {
if (DroppedVarStatsEnabled)
llvm::outs() << "Pass Level, Pass Name, Num of Dropped Variables, Func or "
"Module Name\n";
@@ -62,9 +63,9 @@ void DroppedVariableStats::calculateDroppedStatsAndPrint(
if (DroppedCount > 0) {
llvm::outs() << PassLevel << ", " << PassID << ", " << DroppedCount << ", "
<< FuncOrModName << "\n";
- PassDroppedVariables = true;
+ setPassDroppedVariablesFlag(true);
} else
- PassDroppedVariables = false;
+ setPassDroppedVariablesFlag(false);
}
bool DroppedVariableStats::updateDroppedCount(
diff --git a/llvm/lib/IR/DroppedVariableStatsIR.cpp b/llvm/lib/IR/DroppedVariableStatsIR.cpp
index d07bfd6f4390e..c86974c781a1a 100644
--- a/llvm/lib/IR/DroppedVariableStatsIR.cpp
+++ b/llvm/lib/IR/DroppedVariableStatsIR.cpp
@@ -82,7 +82,7 @@ void DroppedVariableStatsIR::calculateDroppedVarStatsOnModule(
void DroppedVariableStatsIR::registerCallbacks(
PassInstrumentationCallbacks &PIC) {
- if (!DroppedVariableStatsEnabled)
+ if (!getDroppedVariableStatsEnabled())
return;
PIC.registerBeforeNonSkippedPassCallback(
diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index fb3b4bd8b206f..c5df6978d273b 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -126,30 +126,30 @@ void LLVMContext::setDiagnosticHandlerCallBack(
void *DiagnosticContext, bool RespectFilters) {
pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
- pImpl->RespectDiagnosticFilters = RespectFilters;
+ pImpl->setRespectDiagnosticFilters(RespectFilters);
}
void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
bool RespectFilters) {
pImpl->DiagHandler = std::move(DH);
- pImpl->RespectDiagnosticFilters = RespectFilters;
+ pImpl->setRespectDiagnosticFilters(RespectFilters);
}
void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) {
- pImpl->DiagnosticsHotnessRequested = Requested;
+ pImpl->setDiagnosticsHotnessRequested(Requested);
}
bool LLVMContext::getDiagnosticsHotnessRequested() const {
- return pImpl->DiagnosticsHotnessRequested;
+ return pImpl->getDiagnosticsHotnessRequested();
}
void LLVMContext::setDiagnosticsHotnessThreshold(std::optional<uint64_t> Threshold) {
pImpl->DiagnosticsHotnessThreshold = Threshold;
}
void LLVMContext::setMisExpectWarningRequested(bool Requested) {
- pImpl->MisExpectWarningRequested = Requested;
+ pImpl->setMisExpectWarningRequested(Requested);
}
bool LLVMContext::getMisExpectWarningRequested() const {
- return pImpl->MisExpectWarningRequested;
+ return pImpl->getMisExpectWarningRequested();
}
uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
return pImpl->DiagnosticsHotnessThreshold.value_or(UINT64_MAX);
@@ -256,7 +256,7 @@ void LLVMContext::diagnose(const DiagnosticInfo &DI) {
if (pImpl->DiagHandler) {
if (DI.getSeverity() == DS_Error)
pImpl->DiagHandler->HasErrors = true;
- if ((!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
+ if ((!pImpl->getRespectDiagnosticFilters() || isDiagnosticEnabled(DI)) &&
pImpl->DiagHandler->handleDiagnostics(DI))
return;
}
@@ -331,7 +331,7 @@ void LLVMContext::deleteGC(const Function &Fn) {
}
bool LLVMContext::shouldDiscardValueNames() const {
- return pImpl->DiscardValueNames;
+ return pImpl->getDiscardValueNames();
}
bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }
@@ -346,7 +346,7 @@ void LLVMContext::enableDebugTypeODRUniquing() {
void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
void LLVMContext::setDiscardValueNames(bool Discard) {
- pImpl->DiscardValueNames = Discard;
+ pImpl->setDiscardValueNames(Discard);
}
OptPassGate &LLVMContext::getOptPassGate() const {
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index d02d57e4c0197..394a01fe75b5f 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -27,6 +27,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Constants.h"
@@ -1661,8 +1662,12 @@ class LLVMContextImpl {
std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
std::unique_ptr<DiagnosticHandler> DiagHandler;
- bool RespectDiagnosticFilters = false;
- bool DiagnosticsHotnessRequested = false;
+ bool getRespectDiagnosticFilters() const { return Metadatas.getFlag(0); }
+ void setRespectDiagnosticFilters(bool Value) { Metadatas.setFlag(0, Value); }
+ bool getDiagnosticsHotnessRequested() const { return Metadatas.getFlag(1); }
+ void setDiagnosticsHotnessRequested(bool Value) {
+ Metadatas.setFlag(1, Value);
+ }
/// The minimum hotness value a diagnostic needs in order to be included in
/// optimization diagnostics.
///
@@ -1686,7 +1691,8 @@ class LLVMContextImpl {
/// The percentage of difference between profiling branch weights and
/// llvm.expect branch weights to tolerate when emiting MisExpect diagnostics
std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
- bool MisExpectWarningRequested = false;
+ bool getMisExpectWarningRequested() const { return Metadatas.getFlag(2); }
+ void setMisExpectWarningRequested(bool Value) { Metadatas.setFlag(2, Value); }
/// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
std::unique_ptr<LLVMRemarkStreamer> LLVMRS;
@@ -1845,7 +1851,7 @@ class LLVMContextImpl {
StringMap<unsigned> CustomMDKindNames;
/// Collection of metadata attachments in this context.
- SmallVector<MDAttachment, 0> Metadatas;
+ llvm::SmallVectorWithFlags<MDAttachment, 0, 4> Metadatas;
/// Index of first free Metadatas entry, linked list via MDAttachment::Next.
unsigned MetadataRecycleHead = 0;
/// Number of currently unused metadata entries. Only used/updated in debug
@@ -1903,7 +1909,8 @@ class LLVMContextImpl {
/// Flag to indicate if Value (other than GlobalValue) retains their name or
/// not.
- bool DiscardValueNames = false;
+ bool getDiscardValueNames() const { return Metadatas.getFlag(3); }
+ void setDiscardValueNames(bool Value) { Metadatas.setFlag(3, Value); }
LLVMContextImpl(LLVMContext &C);
~LLVMContextImpl();
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index d33d6bdd32030..aea7c3ef71b73 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -1201,7 +1201,7 @@ void PMDataManager::dumpUsedSet(const Pass *P) const {
}
void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
- const AnalysisUsage::VectorType &Set) const {
+ ArrayRef<AnalysisID> Set) const {
assert(PassDebugging >= Details);
if (Set.empty())
return;
diff --git a/llvm/lib/IR/PassTimingInfo.cpp b/llvm/lib/IR/PassTimingInfo.cpp
index 3c5b85d3d691e..8492886198377 100644
--- a/llvm/lib/IR/PassTimingInfo.cpp
+++ b/llvm/lib/IR/PassTimingInfo.cpp
@@ -167,7 +167,7 @@ void llvm::reportAndResetTimings(raw_ostream *OutStream) {
/// Each time it creates a new timer.
Timer &TimePassesHandler::getPassTimer(StringRef PassID, bool IsPass) {
TimerGroup &TG = IsPass ? PassTG : AnalysisTG;
- if (!PerRun) {
+ if (!getPerRun()) {
TimerVector &Timers = TimingData[PassID];
if (Timers.size() == 0)
Timers.emplace_back(new Timer(PassID, PassID, TG));
@@ -189,7 +189,8 @@ Timer &TimePassesHandler::getPassTimer(StringRef PassID, bool IsPass) {
}
TimePassesHandler::TimePassesHandler(bool Enabled, bool PerRun)
- : Enabled(Enabled), PerRun(PerRun) {}
+ : AnalysisActiveTimerStack(decltype(AnalysisActiveTimerStack)::withFlags(
+ unsigned(Enabled) | (unsigned(PerRun) << 1))) {}
TimePassesHandler::TimePassesHandler()
: TimePassesHandler(TimePassesIsEnabled, TimePassesPerRun) {}
@@ -199,7 +200,7 @@ void TimePassesHandler::setOutStream(raw_ostream &Out) {
}
void TimePassesHandler::print() {
- if (!Enabled)
+ if (!getEnabled())
return;
std::unique_ptr<raw_ostream> MaybeCreated;
raw_ostream *OS = OutStream;
@@ -303,7 +304,7 @@ void TimePassesHandler::stopAnalysisTimer(StringRef PassID) {
}
void TimePassesHandler::registerCallbacks(PassInstrumentationCallbacks &PIC) {
- if (!Enabled)
+ if (!getEnabled())
return;
PIC.registerBeforeNonSkippedPassCallback(
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index ee4ef7d1dd53d..f94572b50aed3 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -57,6 +57,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -178,10 +179,12 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// Whether we've seen a call to @llvm.localescape in this function
/// already.
- bool SawFrameEscape;
+ bool getSawFrameEscape() const { return NoAliasScopeDecls.getFlag(0); }
+ void setSawFrameEscape(bool Value) { NoAliasScopeDecls.setFlag(0, Value); }
/// Whether the current function has a DISubprogram attached to it.
- bool HasDebugInfo = false;
+ bool getHasDebugInfo() const { return NoAliasScopeDecls.getFlag(1); }
+ void setHasDebugInfo(bool Value) { NoAliasScopeDecls.setFlag(1, Value); }
/// Stores the count of how many objects were passed to llvm.localescape for a
/// given function and the largest index passed to llvm.localrecover.
@@ -216,7 +219,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
TBAAVerifier TBAAVerifyHelper;
ConvergenceVerifier ConvergenceVerifyHelper;
- SmallVector<IntrinsicInst *, 4> NoAliasScopeDecls;
+ llvm::SmallVectorWithFlags<IntrinsicInst *, 4, 2> NoAliasScopeDecls;
void checkAtomicMemAccessSize(Type *Ty, const Instruction *I);
@@ -224,7 +227,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
explicit Verifier(raw_ostream *OS, bool ShouldTreatBrokenDebugInfoAsError,
const Module &M)
: VerifierSupport(OS, M), LandingPadResultTy(nullptr),
- SawFrameEscape(false), TBAAVerifyHelper(this) {
+ TBAAVerifyHelper(this) {
TreatBrokenDebugInfoAsError = ShouldTreatBrokenDebugInfoAsError;
}
@@ -277,7 +280,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
DebugFnArgs.clear();
DIScopeChainReachesCycle.clear();
LandingPadResultTy = nullptr;
- SawFrameEscape = false;
+ setSawFrameEscape(false);
SiblingFuncletInfo.clear();
verifyNoAliasScopeDecl();
NoAliasScopeDecls.clear();
@@ -3542,8 +3545,8 @@ void Verifier::visitFunction(const Function &F) {
}
auto *N = F.getSubprogram();
- HasDebugInfo = (N != nullptr);
- if (!HasDebugInfo)
+ setHasDebugInfo((N != nullptr));
+ if (!getHasDebugInfo())
return;
// Check that all !dbg attachments lead to back to N.
@@ -6675,8 +6678,8 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
BasicBlock *BB = Call.getParent();
Check(BB->isEntryBlock(), "llvm.localescape used outside of entry block",
Call);
- Check(!SawFrameEscape, "multiple calls to llvm.localescape in one function",
- Call);
+ Check(!getSawFrameEscape(),
+ "multiple calls to llvm.localescape in one function", Call);
for (Value *Arg : Call.args()) {
if (isa<ConstantPointerNull>(Arg))
continue; // Null values are allowed as placeholders.
@@ -6685,7 +6688,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
"llvm.localescape only accepts static allocas", Call);
}
FrameEscapeInfo[BB->getParent()].first = Call.arg_size();
- SawFrameEscape = true;
+ setSawFrameEscape(true);
break;
}
case Intrinsic::localrecover: {
@@ -7839,7 +7842,7 @@ void Verifier::verifyFnArgs(const DbgVariableRecord &DVR) {
// This function does not take the scope of noninlined function arguments into
// account. Don't run it if current function is nodebug, because it may
// contain inlined debug intrinsics.
- if (!HasDebugInfo)
+ if (!getHasDebugInfo())
return;
// For performance reasons only check non-inlined ones.
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 50232bf87d257..a19d0158d42da 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -652,7 +652,7 @@ Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) {
}
File->Mods = FOrErr->Mods;
- File->Strtab = std::move(FOrErr->Strtab);
+ File->Strtab.assign(std::move(FOrErr->Strtab));
return std::move(File);
}
@@ -826,7 +826,7 @@ static void writeToResolutionFile(raw_ostream &OS, InputFile *Input,
Error LTO::add(std::unique_ptr<InputFile> InputPtr,
ArrayRef<SymbolResolution> Res) {
llvm::TimeTraceScope timeScope("LTO add input", InputPtr->getName());
- assert(!CalledGetMaxTasks);
+ assert(!getCalledGetMaxTasks());
Expected<std::shared_ptr<InputFile>> InputOrErr =
addInput(std::move(InputPtr));
@@ -893,7 +893,7 @@ LTO::addModule(InputFile &Input, ArrayRef<SymbolResolution> InputRes,
// If any of the modules inside of a input bitcode file was compiled with
// ThinLTO, we assume that the whole input file also was compiled with
// ThinLTO.
- Input.IsThinLTO |= IsThinLTO;
+ Input.setIsThinLTO(Input.getIsThinLTO() | (IsThinLTO));
auto ModSyms = Input.module_symbols(ModI);
addModuleToGlobalRes(ModSyms, Res,
@@ -1267,7 +1267,7 @@ LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
}
unsigned LTO::getMaxTasks() const {
- CalledGetMaxTasks = true;
+ setCalledGetMaxTasks(true);
auto ModuleCount = ThinLTO.ModulesToCompile ? ThinLTO.ModulesToCompile->size()
: ThinLTO.ModuleMap.size();
return RegularLTO.ParallelCodeGenParallelismLevel + ModuleCount;
@@ -2322,7 +2322,8 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
LLVM_DEBUG(dbgs() << "[TwoRounds] Running the first round of codegen\n");
auto FirstRoundLTO = std::make_unique<FirstRoundThinBackend>(
Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
- CG.AddStream, CG.Cache, BitcodeLibFuncs, IR.AddStream, IR.Cache);
+ CG.AddStream, CG.Cache, ArrayRef<StringRef>(BitcodeLibFuncs),
+ IR.AddStream, IR.Cache);
if (Error E = RunBackends(FirstRoundLTO.get()))
return E;
@@ -2338,7 +2339,8 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
LLVM_DEBUG(dbgs() << "[TwoRounds] Running the second round of codegen\n");
auto SecondRoundLTO = std::make_unique<SecondRoundThinBackend>(
Conf, ThinLTO.CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
- AddStream, Cache, BitcodeLibFuncs, IR.getResult(), CombinedHash);
+ AddStream, Cache, ArrayRef<StringRef>(BitcodeLibFuncs), IR.getResult(),
+ CombinedHash);
return RunBackends(SecondRoundLTO.get());
}
diff --git a/llvm/lib/MC/DXContainerInfo.cpp b/llvm/lib/MC/DXContainerInfo.cpp
index 909207b39ee17..d747f4db324cd 100644
--- a/llvm/lib/MC/DXContainerInfo.cpp
+++ b/llvm/lib/MC/DXContainerInfo.cpp
@@ -199,7 +199,7 @@ template <typename VecT> static void clearAndReserve(VecT &Vec, size_t N) {
}
void SourceInfoBuilder::computeEntries() {
- IsFilled = true;
+ setIsFilled(true);
clearAndReserve(BaseData.Names.Entries, FileNamesAndContents.size());
clearAndReserve(BaseData.Contents.Entries, FileNamesAndContents.size());
for (const auto &NameContent : FileNamesAndContents) {
@@ -226,11 +226,11 @@ void SourceInfoBuilder::recomputeAfterCompression(uint32_t CompressedSize) {
}
void SourceInfoBuilder::finalize() {
- assert(IsFilled && "SourceInfo::computeEntries() must be called before "
- "SourceInfo::computeUncompressed()");
+ assert(getIsFilled() && "SourceInfo::computeEntries() must be called before "
+ "SourceInfo::computeUncompressed()");
assert(CompressionType && "Compression type must be set.");
- IsFinalized = true;
+ setIsFinalized(true);
BaseData.Contents.computeUncompressed(*CompressionType);
BaseData.Names.compute();
@@ -279,7 +279,7 @@ void SourceInfoBuilder::finalize() {
}
void SourceInfoBuilder::write(raw_ostream &OS) const {
- assert(IsFinalized &&
+ assert(getIsFinalized() &&
"SourceInfo::finalize() must be called before SourceInfo::write()");
writeStruct(OS, BaseData.Parameters);
diff --git a/llvm/lib/MC/DXContainerPSVInfo.cpp b/llvm/lib/MC/DXContainerPSVInfo.cpp
index a6aa556535b48..5577801660698 100644
--- a/llvm/lib/MC/DXContainerPSVInfo.cpp
+++ b/llvm/lib/MC/DXContainerPSVInfo.cpp
@@ -48,7 +48,7 @@ ProcessElementList(StringTableBuilder &StrTabBuilder,
FinalElement.StartRow = El.StartRow;
FinalElement.Cols = El.Cols;
FinalElement.StartCol = El.StartCol;
- FinalElement.Allocated = El.Allocated;
+ FinalElement.Allocated = El.getAllocated();
FinalElement.Kind = El.Kind;
FinalElement.Type = El.Type;
FinalElement.Mode = El.Mode;
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index db4aa48138e04..10e07efbb8de2 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -89,9 +89,9 @@ MCAssembler::MCAssembler(MCContext &Context,
}
void MCAssembler::reset() {
- HasLayout = false;
- HasFinalLayout = false;
- RelaxAll = false;
+ setHasLayout(false);
+ setHasFinalLayout(false);
+ setRelaxAllFlag(false);
BundleAlign.reset();
Sections.clear();
Symbols.clear();
@@ -338,7 +338,7 @@ uint64_t MCAssembler::getSymbolOffset(const MCSymbol &S) const {
}
const MCSymbol *MCAssembler::getBaseSymbol(const MCSymbol &Symbol) const {
- assert(HasLayout);
+ assert(getHasLayout());
if (!Symbol.isVariable())
return &Symbol;
@@ -373,7 +373,7 @@ const MCSymbol *MCAssembler::getBaseSymbol(const MCSymbol &Symbol) const {
uint64_t MCAssembler::getSectionAddressSize(const MCSection &Sec) const {
const MCFragment &F = *Sec.curFragList()->Tail;
- assert(HasLayout && F.getKind() == MCFragment::FT_Data);
+ assert(getHasLayout() && F.getKind() == MCFragment::FT_Data);
return getFragmentOffset(F) + F.getSize();
}
@@ -697,7 +697,7 @@ void MCAssembler::layout() {
}
// Layout until everything fits.
- this->HasLayout = true;
+ this->setHasLayout(true);
for (MCSection &Sec : *this)
layoutSection(Sec);
unsigned FirstStable = Sections.size();
@@ -726,7 +726,7 @@ void MCAssembler::layout() {
// Fragment sizes are finalized. For RISC-V linker relaxation, this flag
// helps check whether a PC-relative fixup is fully resolved.
- this->HasFinalLayout = true;
+ this->setHasFinalLayout(true);
// Stores the current .reloc group for each fragment.
//
@@ -810,7 +810,7 @@ void MCAssembler::Finish() {
if (!getContext().hadError())
stats::ObjectBytes += getWriter().writeObject();
- HasLayout = false;
+ setHasLayout(false);
assert(PendingErrors.empty());
}
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index 335934a7793e4..9254c039e7a92 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -226,7 +226,7 @@ void CodeViewContext::emitFileChecksums(MCObjectStreamer &OS) {
OS.emitLabel(FileEnd);
- ChecksumOffsetsAssigned = true;
+ setChecksumOffsetsAssigned(true);
}
// Output checksum table offset of the given file number. It is possible that
@@ -240,7 +240,7 @@ void CodeViewContext::emitFileChecksumOffset(MCObjectStreamer &OS,
if (Idx >= Files.size())
Files.resize(Idx + 1);
- if (ChecksumOffsetsAssigned) {
+ if (getChecksumOffsetsAssigned()) {
OS.emitSymbolValue(Files[Idx].ChecksumTableOffset, 4);
return;
}
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 935b0888bf693..35c05900fb0d4 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -70,8 +70,8 @@ MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo &mai,
SrcMgr(mgr), InlineSrcMgr(nullptr), DiagHandler(defaultDiagHandler),
MAI(mai), MRI(&mri), MSTI(&msti), Symbols(Allocator),
InlineAsmUsedLabelNames(Allocator),
- CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
- AutoReset(DoAutoReset) {
+ CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0) {
+ DebugPrefixMap.setFlag(2, DoAutoReset);
const MCTargetOptions &TO = getTargetOptions();
SaveTempLabels = TO.MCSaveTempLabels;
if (SaveTempLabels)
@@ -123,7 +123,7 @@ const MCTargetOptions &MCContext::getTargetOptions() const {
}
MCContext::~MCContext() {
- if (AutoReset)
+ if (DebugPrefixMap.getFlag(2))
reset();
// NOTE: The symbols are all allocated out of a bump pointer allocator,
@@ -190,7 +190,7 @@ void MCContext::reset() {
GenDwarfForAssembly = false;
GenDwarfFileNumber = 0;
- HadError = false;
+ DebugPrefixMap.setFlag(3, false);
}
//===----------------------------------------------------------------------===//
@@ -363,7 +363,7 @@ MCSymbol *MCContext::createRenamableSymbol(const Twine &Name,
}
MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {
- if (!UseNamesOnTempLabels)
+ if (!DebugPrefixMap.getFlag(1))
return createSymbolImpl(nullptr, /*IsTemporary=*/true);
return createRenamableSymbol(MAI.getInternalSymbolPrefix() + Name,
AlwaysAddSuffix, /*IsTemporary=*/true);
@@ -379,7 +379,7 @@ MCSymbol *MCContext::createBlockSymbol(const Twine &Name, bool AlwaysEmit) {
return getOrCreateSymbol(MAI.getInternalSymbolPrefix() + Name);
bool IsTemporary = !SaveTempLabels;
- if (IsTemporary && !UseNamesOnTempLabels)
+ if (IsTemporary && !DebugPrefixMap.getFlag(1))
return createSymbolImpl(nullptr, IsTemporary);
return createRenamableSymbol(MAI.getInternalSymbolPrefix() + Name,
/*AlwaysAddSuffix=*/false, IsTemporary);
@@ -1082,7 +1082,7 @@ CodeViewContext &MCContext::getCVContext() {
void MCContext::diagnose(const SMDiagnostic &SMD) {
assert(DiagHandler && "MCContext::DiagHandler is not set");
if (SMD.getKind() == SourceMgr::DK_Error)
- HadError = true;
+ DebugPrefixMap.setFlag(3, true);
bool UseInlineSrcMgr = false;
const SourceMgr *SMP = nullptr;
if (SrcMgr) {
@@ -1127,7 +1127,7 @@ void MCContext::reportCommon(
}
void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
- HadError = true;
+ DebugPrefixMap.setFlag(3, true);
reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {
D = SMP->GetMessage(Loc, SourceMgr::DK_Error, Msg);
});
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index da8e057f0f9ee..476f5e9b14e8a 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -511,9 +511,9 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
// directory index. We don't track file size/timestamp so don't emit them
// in the v5 table. Emit MD5 checksums and source if we have them.
uint64_t Entries = 2;
- if (HasAllMD5)
+ if (!MCDwarfDirs.getFlag(1))
Entries += 1;
- if (HasAnySource)
+ if (hasAnySource())
Entries += 1;
MCOS->emitInt8(Entries);
MCOS->emitULEB128IntValue(dwarf::DW_LNCT_path);
@@ -521,11 +521,11 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
: dwarf::DW_FORM_string);
MCOS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
MCOS->emitULEB128IntValue(dwarf::DW_FORM_udata);
- if (HasAllMD5) {
+ if (!MCDwarfDirs.getFlag(1)) {
MCOS->emitULEB128IntValue(dwarf::DW_LNCT_MD5);
MCOS->emitULEB128IntValue(dwarf::DW_FORM_data16);
}
- if (HasAnySource) {
+ if (hasAnySource()) {
MCOS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
MCOS->emitULEB128IntValue(LineStr ? dwarf::DW_FORM_line_strp
: dwarf::DW_FORM_string);
@@ -540,9 +540,10 @@ void MCDwarfLineTableHeader::emitV5FileDirTables(
assert((!RootFile.Name.empty() || MCDwarfFiles.size() >= 1) &&
"No root file and no .file directives");
emitOneV5FileEntry(MCOS, RootFile.Name.empty() ? MCDwarfFiles[1] : RootFile,
- HasAllMD5, HasAnySource, LineStr);
+ !MCDwarfDirs.getFlag(1), hasAnySource(), LineStr);
for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)
- emitOneV5FileEntry(MCOS, MCDwarfFiles[i], HasAllMD5, HasAnySource, LineStr);
+ emitOneV5FileEntry(MCOS, MCDwarfFiles[i], !MCDwarfDirs.getFlag(1),
+ hasAnySource(), LineStr);
}
std::pair<MCSymbol *, MCSymbol *>
@@ -659,7 +660,7 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, StringRef &FileName,
// If any files have embedded source, they all must.
if (MCDwarfFiles.empty()) {
trackMD5Usage(Checksum.has_value());
- HasAnySource |= Source.has_value();
+ trackSource(Source.has_value());
}
if (DwarfVersion >= 5 && isRootFile(RootFile, Directory, FileName, Checksum))
return 0;
@@ -719,7 +720,7 @@ MCDwarfLineTableHeader::tryGetFile(StringRef &Directory, StringRef &FileName,
trackMD5Usage(Checksum.has_value());
File.Source = Source;
if (Source.has_value())
- HasAnySource = true;
+ trackSource(true);
// return the allocated FileNumber.
return FileNumber;
@@ -1059,7 +1060,7 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// AT_name, the name of the source file. Reconstruct from the first directory
// and file table entries.
- const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs();
+ ArrayRef<std::string> MCDwarfDirs = context.getMCDwarfDirs();
if (MCDwarfDirs.size() > 0) {
MCOS->emitBytes(MCDwarfDirs[0]);
MCOS->emitBytes(sys::path::get_separator());
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index efe08d7e09a84..5a01079505b87 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -86,7 +86,7 @@ void MCELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
getContext().reportError(
getStartTokLoc(), "unterminated .bundle_lock when changing a section");
// Clean up bundle state to allow continuing.
- BundleLocked = false;
+ setBundleLocked(false);
BundleBA = nullptr;
}
auto *SectionELF = static_cast<const MCSectionELF *>(Section);
@@ -316,9 +316,9 @@ void MCELFStreamer::emitIdent(StringRef IdentString) {
".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
pushSection();
switchSection(Comment);
- if (!SeenIdent) {
+ if (!getSeenIdent()) {
emitInt8(0);
- SeenIdent = true;
+ setSeenIdent(true);
}
emitBytes(IdentString);
emitInt8(0);
@@ -363,7 +363,7 @@ void MCELFStreamer::emitBundleLock(bool AlignToEnd,
return getContext().reportError(
Loc, ".bundle_lock is only allowed in an executable section");
- BundleLocked = true;
+ setBundleLocked(true);
BundleBA =
newSpecialFragment<MCBoundaryAlignFragment>(Asm.getBundleAlign(), STI);
BundleBA->setAlignToEnd(AlignToEnd);
@@ -380,7 +380,7 @@ void MCELFStreamer::emitBundleUnlock(const MCSubtargetInfo &STI) {
return getContext().reportError(Loc,
".bundle_unlock without matching lock");
- BundleLocked = false;
+ setBundleLocked(false);
MCFragment *CF = getCurrentFragment();
BundleBA->setLastFragment(CF);
@@ -464,6 +464,7 @@ void MCELFStreamer::finishImpl() {
MCSection *DummyAttributeSection = nullptr;
createAttributesSection("gnu", ".gnu.attributes", ELF::SHT_GNU_ATTRIBUTES,
DummyAttributeSection, GNUAttributes);
+ GNUAttributes.clear();
}
if (Ctx.getTargetTriple().isLFI())
@@ -536,8 +537,8 @@ MCELFStreamer::getAttributeItem(unsigned Attribute) {
return nullptr;
}
-size_t MCELFStreamer::calculateContentSize(
- SmallVector<AttributeItem, 64> &AttrsVec) const {
+size_t
+MCELFStreamer::calculateContentSize(ArrayRef<AttributeItem> AttrsVec) const {
size_t Result = 0;
for (const AttributeItem &Item : AttrsVec) {
switch (Item.Type) {
@@ -561,9 +562,10 @@ size_t MCELFStreamer::calculateContentSize(
return Result;
}
-void MCELFStreamer::createAttributesSection(
- StringRef Vendor, const Twine &Section, unsigned Type,
- MCSection *&AttributeSection, SmallVector<AttributeItem, 64> &AttrsVec) {
+void MCELFStreamer::createAttributesSection(StringRef Vendor,
+ const Twine &Section, unsigned Type,
+ MCSection *&AttributeSection,
+ ArrayRef<AttributeItem> AttrsVec) {
// <format-version>
// [ <section-length> "vendor-name"
// [ <file-tag> <size> <attribute>*
@@ -619,8 +621,6 @@ void MCELFStreamer::createAttributesSection(
break;
}
}
-
- AttrsVec.clear();
}
void MCELFStreamer::createAttributesWithSubsection(
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 8fb2d7bc90c52..6547b4e695d75 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -32,7 +32,7 @@ MCObjectStreamer::MCObjectStreamer(MCContext &Context,
: MCStreamer(Context),
Assembler(std::make_unique<MCAssembler>(
Context, std::move(TAB), std::move(Emitter), std::move(OW))),
- EmitEHFrame(true), EmitDebugFrame(false), EmitSFrame(false) {
+ FragStorage(decltype(this->FragStorage)::withFlags(1)) {
assert(Assembler->getBackendPtr() && Assembler->getEmitterPtr());
IsObj = true;
setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
@@ -173,9 +173,9 @@ void MCObjectStreamer::reset() {
Assembler->reset();
Assembler->setRelaxAll(getContext().getTargetOptions().MCRelaxAll);
}
- EmitEHFrame = true;
- EmitDebugFrame = false;
- BundleLocked = false;
+ setEmitEHFrame(true);
+ setEmitDebugFrame(false);
+ setBundleLocked(false);
FragStorage.clear();
FragSpace = 0;
SpecialFragAllocator.Reset();
@@ -193,12 +193,12 @@ void MCObjectStreamer::emitFrames() {
if (!getNumFrameInfos())
return;
- if (EmitEHFrame)
+ if (getEmitEHFrame())
MCDwarfFrameEmitter::emit(*this, true);
- if (EmitDebugFrame)
+ if (getEmitDebugFrame())
MCDwarfFrameEmitter::emit(*this, false);
- if (EmitSFrame || getContext().getTargetOptions().EmitSFrameUnwind)
+ if (getEmitSFrame() || getContext().getTargetOptions().EmitSFrameUnwind)
MCSFrameEmitter::emit(*this);
}
@@ -208,9 +208,9 @@ void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
void MCObjectStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) {
MCStreamer::emitCFISections(EH, Debug, SFrame);
- EmitEHFrame = EH;
- EmitDebugFrame = Debug;
- EmitSFrame = SFrame;
+ setEmitEHFrame(EH);
+ setEmitDebugFrame(Debug);
+ setEmitSFrame(SFrame);
}
void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
@@ -426,7 +426,7 @@ void MCObjectStreamer::emitInstruction(const MCInst &Inst,
// Bundling emits one relaxable fragment per instruction so that finishLayout
// can fold padding into instruction encodings.
if (Assembler.isBundlingEnabled()) {
- if (BundleLocked || Assembler.getRelaxAll())
+ if (getBundleLocked() || Assembler.getRelaxAll())
emitInstToFragment(relaxToFixpoint(Inst), STI);
else
emitInstToFragment(Inst, STI);
diff --git a/llvm/lib/MC/MCObjectWriter.cpp b/llvm/lib/MC/MCObjectWriter.cpp
index 7cbd0b489d9f6..c1dd11f1f51e7 100644
--- a/llvm/lib/MC/MCObjectWriter.cpp
+++ b/llvm/lib/MC/MCObjectWriter.cpp
@@ -25,8 +25,7 @@ MCContext &MCObjectWriter::getContext() const { return Asm->getContext(); }
void MCObjectWriter::reset() {
FileNames.clear();
AddrsigSyms.clear();
- EmitAddrsigSection = false;
- SubsectionsViaSymbols = false;
+ FileNames.setFlags(0);
CGProfile.clear();
}
diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp
index cb7bb903276d4..979e6051cae45 100644
--- a/llvm/lib/MC/MCParser/AsmLexer.cpp
+++ b/llvm/lib/MC/MCParser/AsmLexer.cpp
@@ -495,7 +495,7 @@ AsmToken AsmLexer::LexDigit() {
// MASM default-radix integers: [0-9a-fA-F]+
// (All other integer literals have a radix specifier.)
- if (LexMasmIntegers && UseMasmDefaultRadix) {
+ if (LexMasmIntegers && CurTok.getFlag(0)) {
CurPtr = findLastDigit(CurPtr, 16);
StringRef Result(TokStart, CurPtr - TokStart);
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index b50f27cca1be9..64f6054d6c17d 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -159,10 +160,12 @@ class AsmParser : public MCAsmParser {
CppHashInfoTy CppHashInfo;
/// Have we seen any file line comment.
- bool HadCppHashFilename = false;
+ bool getHadCppHashFilename() const { return DirLabels.getFlag(0); }
+ void setHadCppHashFilename(bool Value) { DirLabels.setFlag(0, Value); }
/// List of forward directional labels for diagnosis at the end.
- SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
+ llvm::SmallVectorWithFlags<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4>
+ DirLabels;
SmallSet<StringRef, 2> LTODiscardSymbols;
@@ -767,7 +770,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI, unsigned CB = 0)
: MCAsmParser(Ctx, Out, SM, MAI), CurBuffer(CB ? CB : SM.getMainFileID()),
MacrosEnabledFlag(true) {
- HadError = false;
+ setHadError(false);
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -817,7 +820,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
}
AsmParser::~AsmParser() {
- assert((HadError || ActiveMacros.empty()) &&
+ assert((getHadError() || ActiveMacros.empty()) &&
"Unexpected active macro instantiation!");
// Remove MCStreamer's reference to the parser SMLoc.
@@ -851,7 +854,7 @@ bool AsmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
}
bool AsmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
- HadError = true;
+ setHadError(true);
printMessage(L, SourceMgr::DK_Error, Msg, Range);
printMacroInstantiations();
return true;
@@ -875,7 +878,7 @@ bool AsmParser::enterIncludeFile(const std::string &Filename) {
bool AsmParser::processIncbinFile(const std::string &Filename, int64_t Skip,
const MCExpr *Count, SMLoc Loc) {
// The .incbin file cannot introduce new symbols.
- if (SymbolScanningMode)
+ if (getSymbolScanningModeFlag())
return false;
// The buffer is consumed only by emitBytes. Skip the NUL termination to
@@ -969,7 +972,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Prime the lexer.
Lex();
- HadError = false;
+ setHadError(false);
AsmCond StartingCondState = TheCondState;
SmallVector<AsmRewrite, 4> AsmStrRewrites;
@@ -1066,14 +1069,14 @@ 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) {
+ if (!getHadError() && !NoFinalize) {
if (auto *TS = Out.getTargetStreamer())
TS->emitConstantPools();
Out.finish(Lexer.getLoc());
}
- return HadError || getContext().hadError();
+ return getHadError() || getContext().hadError();
}
bool AsmParser::checkForValidSection() {
@@ -2393,8 +2396,8 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo) {
CppHashInfo.Filename = Filename;
CppHashInfo.LineNumber = LineNumber;
CppHashInfo.Buf = CurBuffer;
- if (!HadCppHashFilename) {
- HadCppHashFilename = true;
+ if (!getHadCppHashFilename()) {
+ setHadCppHashFilename(true);
// If we haven't encountered any .file directives, then the first #line
// directive describes the "root" file and directory of the compilation
// unit.
diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp
index ac525f175fd54..85068f9ec059e 100644
--- a/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -975,7 +975,7 @@ MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI, struct tm TM, unsigned CB)
: MCAsmParser(Ctx, Out, SM, MAI), CurBuffer(CB ? CB : SM.getMainFileID()),
TM(TM) {
- HadError = false;
+ setHadError(false);
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
SavedDiagContext = SrcMgr.getDiagContext();
@@ -1002,7 +1002,7 @@ MasmParser::MasmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
}
MasmParser::~MasmParser() {
- assert((HadError || ActiveMacros.empty()) &&
+ assert((getHadError() || ActiveMacros.empty()) &&
"Unexpected active macro instantiation!");
// Restore the saved diagnostics handler and context for use during
@@ -1037,7 +1037,7 @@ bool MasmParser::Warning(SMLoc L, const Twine &Msg, SMRange Range) {
}
bool MasmParser::printError(SMLoc L, const Twine &Msg, SMRange Range) {
- HadError = true;
+ setHadError(true);
printMessage(L, SourceMgr::DK_Error, Msg, Range);
printMacroInstantiations();
return true;
@@ -1212,7 +1212,7 @@ bool MasmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Prime the lexer.
Lex();
- HadError = false;
+ setHadError(false);
AsmCond StartingCondState = TheCondState;
SmallVector<AsmRewrite, 4> AsmStrRewrites;
@@ -1268,10 +1268,10 @@ 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)
+ if (!getHadError() && !NoFinalize)
Out.finish(Lexer.getLoc());
- return HadError || getContext().hadError();
+ return getHadError() || getContext().hadError();
}
bool MasmParser::checkForValidSection() {
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index 790f7595807b9..021d5f41b6135 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -754,7 +754,7 @@ bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
if (!hasReliableSymbolDifference) {
if (!SA.isInSection() || &SecA != &SecB ||
(!SA.isTemporary() && FB.getAtom() != SA.getFragment()->getAtom() &&
- SubsectionsViaSymbols))
+ getSubsectionsViaSymbols()))
return false;
return true;
}
@@ -917,7 +917,7 @@ uint64_t MachObjectWriter::writeObject() {
// Write the prolog, starting with the header and load command...
writeHeader(MachO::MH_OBJECT, NumLoadCommands, LoadCommandsSize,
- SubsectionsViaSymbols);
+ getSubsectionsViaSymbols());
uint32_t Prot =
MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE;
writeSegmentLoadCommand("", NumSections, 0, VMSize, SectionDataStart,
diff --git a/llvm/lib/ObjCopy/Archive.cpp b/llvm/lib/ObjCopy/Archive.cpp
index 191174102c66f..6e3723ec79b2d 100644
--- a/llvm/lib/ObjCopy/Archive.cpp
+++ b/llvm/lib/ObjCopy/Archive.cpp
@@ -38,7 +38,7 @@ objcopy::createNewArchiveMembers(const MultiFormatConfig &Config,
ChildOrErr.takeError());
const CommonConfig &CC = Config.getCommonConfig();
- if (CC.Verbose) {
+ if (CC.getVerbose()) {
StringRef FormatName = getObjectFormatName(*ChildOrErr->get());
printCopyMessage(MemberName(Ar.getFileName()), FormatName,
MemberName(CC.OutputFilename), FormatName);
@@ -51,7 +51,7 @@ objcopy::createNewArchiveMembers(const MultiFormatConfig &Config,
return std::move(E);
Expected<NewArchiveMember> Member = NewArchiveMember::getOldMember(
- Child, Config.getCommonConfig().DeterministicArchives);
+ Child, Config.getCommonConfig().getDeterministicArchives());
if (!Member)
return createFileError(Ar.getFileName(), Member.takeError());
@@ -115,6 +115,6 @@ Error objcopy::executeObjcopyOnArchive(const MultiFormatConfig &Config,
return deepWriteArchive(CommonConfig.OutputFilename, *NewArchiveMembersOrErr,
Ar.hasSymbolTable() ? SymtabWritingMode::NormalSymtab
: SymtabWritingMode::NoSymtab,
- Ar.kind(), CommonConfig.DeterministicArchives,
+ Ar.kind(), CommonConfig.getDeterministicArchives(),
Ar.isThin());
}
diff --git a/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp b/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp
index 96de61737d78f..df312b5065cf6 100644
--- a/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/COFF/COFFObjcopy.cpp
@@ -182,8 +182,9 @@ static Error handleArgs(const CommonConfig &Config,
if (!Config.OnlySection.empty() && !Config.OnlySection.matches(Sec.Name))
return true;
- if (Config.StripDebug || Config.StripAll || Config.StripAllGNU ||
- Config.DiscardMode == DiscardType::All || Config.StripUnneeded) {
+ if (Config.getStripDebug() || Config.getStripAll() ||
+ Config.getStripAllGNU() || Config.DiscardMode == DiscardType::All ||
+ Config.getStripUnneeded()) {
if (isDebugSection(Sec) &&
(Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)
return true;
@@ -195,7 +196,7 @@ static Error handleArgs(const CommonConfig &Config,
return false;
});
- if (Config.OnlyKeepDebug) {
+ if (Config.getOnlyKeepDebug()) {
const data_directory *DebugDir =
Obj.DataDirectories.size() > DEBUG_DIRECTORY
? &Obj.DataDirectories[DEBUG_DIRECTORY]
@@ -214,12 +215,12 @@ static Error handleArgs(const CommonConfig &Config,
}
// StripAll removes all symbols and thus also removes all relocations.
- if (Config.StripAll || Config.StripAllGNU)
+ if (Config.getStripAll() || Config.getStripAllGNU())
for (Section &Sec : Obj.getMutableSections())
Sec.Relocs.clear();
// If we need to do per-symbol removals, initialize the Referenced field.
- if (Config.StripUnneeded || Config.DiscardMode == DiscardType::All ||
+ if (Config.getStripUnneeded() || Config.DiscardMode == DiscardType::All ||
!Config.SymbolsToRemove.empty())
if (Error E = Obj.markSymbols())
return E;
@@ -233,7 +234,7 @@ static Error handleArgs(const CommonConfig &Config,
auto ToRemove = [&](const Symbol &Sym) -> Expected<bool> {
// For StripAll, all relocations have been stripped and we remove all
// symbols.
- if (Config.StripAll || Config.StripAllGNU)
+ if (Config.getStripAll() || Config.getStripAllGNU())
return true;
if (Config.SymbolsToRemove.matches(Sym.Name)) {
@@ -256,7 +257,7 @@ static Error handleArgs(const CommonConfig &Config,
// local symbol instead of removing all of such.
if (Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC ||
Sym.Sym.SectionNumber == 0)
- if (Config.StripUnneeded ||
+ if (Config.getStripUnneeded() ||
Config.UnneededSymbolsToRemove.matches(Sym.Name))
return true;
diff --git a/llvm/lib/ObjCopy/ConfigManager.cpp b/llvm/lib/ObjCopy/ConfigManager.cpp
index 403b9d1bb922e..19d367b94c654 100644
--- a/llvm/lib/ObjCopy/ConfigManager.cpp
+++ b/llvm/lib/ObjCopy/ConfigManager.cpp
@@ -28,10 +28,11 @@ Expected<const COFFConfig &> ConfigManager::getCOFFConfig() const {
!Common.SymbolsToLocalize.empty() || !Common.SymbolsToWeaken.empty() ||
!Common.SymbolsToKeepGlobal.empty() || !Common.SectionsToRename.empty() ||
!Common.SetSectionAlignment.empty() || !Common.SetSectionType.empty() ||
- Common.ExtractDWO || Common.StripDWO || Common.StripNonAlloc ||
- Common.StripSections || Common.Weaken ||
+ Common.getExtractDWO() || Common.getStripDWO() ||
+ Common.getStripNonAlloc() || Common.getStripSections() ||
+ Common.getWeaken() ||
Common.CompressionType != DebugCompressionType::None ||
- !Common.compressSections.empty() || Common.DecompressDebugSections ||
+ !Common.compressSections.empty() || Common.getDecompressDebugSections() ||
Common.DiscardMode == DiscardType::Locals ||
!Common.SymbolsToAdd.empty() || Common.GapFill != 0 ||
Common.PadTo != 0 || Common.ChangeSectionLMAValAll != 0 ||
@@ -49,12 +50,13 @@ Expected<const MachOConfig &> ConfigManager::getMachOConfig() const {
!Common.SymbolsToKeep.empty() || !Common.SectionsToRename.empty() ||
!Common.UnneededSymbolsToRemove.empty() ||
!Common.SetSectionAlignment.empty() || !Common.SetSectionFlags.empty() ||
- !Common.SetSectionType.empty() || Common.ExtractDWO ||
- Common.PreserveDates || Common.StripAllGNU || Common.StripDWO ||
- Common.StripNonAlloc || Common.StripSections ||
+ !Common.SetSectionType.empty() || Common.getExtractDWO() ||
+ Common.getPreserveDates() || Common.getStripAllGNU() ||
+ Common.getStripDWO() || Common.getStripNonAlloc() ||
+ Common.getStripSections() ||
Common.CompressionType != DebugCompressionType::None ||
- !Common.compressSections.empty() || Common.DecompressDebugSections ||
- Common.StripUnneeded || Common.DiscardMode == DiscardType::Locals ||
+ !Common.compressSections.empty() || Common.getDecompressDebugSections() ||
+ Common.getStripUnneeded() || Common.DiscardMode == DiscardType::Locals ||
!Common.SymbolsToAdd.empty() || Common.GapFill != 0 ||
Common.PadTo != 0 || Common.ChangeSectionLMAValAll != 0 ||
!Common.ChangeSectionAddress.empty() || !Common.ExtractSection.empty())
@@ -78,7 +80,7 @@ Expected<const WasmConfig &> ConfigManager::getWasmConfig() const {
!Common.SetSectionFlags.empty() || !Common.SetSectionType.empty() ||
!Common.SymbolsToRename.empty() ||
Common.CompressionType != DebugCompressionType::None ||
- !Common.compressSections.empty() || Common.DecompressDebugSections ||
+ !Common.compressSections.empty() || Common.getDecompressDebugSections() ||
Common.GapFill != 0 || Common.PadTo != 0 ||
Common.ChangeSectionLMAValAll != 0 ||
!Common.ChangeSectionAddress.empty() || !Common.ExtractSection.empty())
@@ -104,13 +106,14 @@ Expected<const XCOFFConfig &> ConfigManager::getXCOFFConfig() const {
!Common.SymbolsToWeaken.empty() || !Common.SymbolsToKeepGlobal.empty() ||
!Common.SectionsToRename.empty() || !Common.SetSectionAlignment.empty() ||
!Common.SetSectionFlags.empty() || !Common.SetSectionType.empty() ||
- !Common.SymbolsToRename.empty() || Common.ExtractDWO ||
- Common.ExtractMainPartition || Common.OnlyKeepDebug ||
- Common.PreserveDates || Common.StripAllGNU || Common.StripDWO ||
- Common.StripDebug || Common.StripNonAlloc || Common.StripSections ||
- Common.Weaken || Common.StripUnneeded ||
+ !Common.SymbolsToRename.empty() || Common.getExtractDWO() ||
+ Common.getExtractMainPartition() || Common.getOnlyKeepDebug() ||
+ Common.getPreserveDates() || Common.getStripAllGNU() ||
+ Common.getStripDWO() || Common.getStripDebug() ||
+ Common.getStripNonAlloc() || Common.getStripSections() ||
+ Common.getWeaken() || Common.getStripUnneeded() ||
Common.CompressionType != DebugCompressionType::None ||
- !Common.compressSections.empty() || Common.DecompressDebugSections ||
+ !Common.compressSections.empty() || Common.getDecompressDebugSections() ||
Common.GapFill != 0 || Common.PadTo != 0 ||
Common.ChangeSectionLMAValAll != 0 ||
!Common.ChangeSectionAddress.empty() || !Common.ExtractSection.empty()) {
@@ -131,12 +134,13 @@ ConfigManager::getDXContainerConfig() const {
Common.DiscardMode != DiscardType::None || !Common.AddSection.empty() ||
!Common.KeepSection.empty() || !Common.SectionsToRename.empty() ||
!Common.SetSectionAlignment.empty() || !Common.SetSectionFlags.empty() ||
- !Common.SetSectionType.empty() || Common.ExtractDWO ||
- Common.OnlyKeepDebug || Common.StripAllGNU || Common.StripDWO ||
- Common.StripDebug || Common.StripNonAlloc || Common.StripSections ||
- Common.StripUnneeded ||
+ !Common.SetSectionType.empty() || Common.getExtractDWO() ||
+ Common.getOnlyKeepDebug() || Common.getStripAllGNU() ||
+ Common.getStripDWO() || Common.getStripDebug() ||
+ Common.getStripNonAlloc() || Common.getStripSections() ||
+ Common.getStripUnneeded() ||
Common.CompressionType != DebugCompressionType::None ||
- !Common.compressSections.empty() || Common.DecompressDebugSections ||
+ !Common.compressSections.empty() || Common.getDecompressDebugSections() ||
Common.GapFill != 0 || Common.PadTo != 0 ||
Common.ChangeSectionLMAValAll != 0 ||
!Common.ChangeSectionAddress.empty()) {
diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index d448c3adf442f..9e6e504348aca 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -155,17 +155,17 @@ static std::unique_ptr<Writer> createELFWriter(const CommonConfig &Config,
// Depending on the initial ELFT and OutputFormat we need a different Writer.
switch (OutputElfType) {
case ELFT_ELF32LE:
- return std::make_unique<ELFWriter<ELF32LE>>(Obj, Out, !Config.StripSections,
- Config.OnlyKeepDebug);
+ return std::make_unique<ELFWriter<ELF32LE>>(
+ Obj, Out, !Config.getStripSections(), Config.getOnlyKeepDebug());
case ELFT_ELF64LE:
- return std::make_unique<ELFWriter<ELF64LE>>(Obj, Out, !Config.StripSections,
- Config.OnlyKeepDebug);
+ return std::make_unique<ELFWriter<ELF64LE>>(
+ Obj, Out, !Config.getStripSections(), Config.getOnlyKeepDebug());
case ELFT_ELF32BE:
- return std::make_unique<ELFWriter<ELF32BE>>(Obj, Out, !Config.StripSections,
- Config.OnlyKeepDebug);
+ return std::make_unique<ELFWriter<ELF32BE>>(
+ Obj, Out, !Config.getStripSections(), Config.getOnlyKeepDebug());
case ELFT_ELF64BE:
- return std::make_unique<ELFWriter<ELF64BE>>(Obj, Out, !Config.StripSections,
- Config.OnlyKeepDebug);
+ return std::make_unique<ELFWriter<ELF64BE>>(
+ Obj, Out, !Config.getStripSections(), Config.getOnlyKeepDebug());
}
llvm_unreachable("Invalid output format");
}
@@ -225,7 +225,7 @@ Error Object::compressOrDecompressSections(const CommonConfig &Config) {
if (!(Sec.Flags & SHF_ALLOC) && StringRef(Sec.Name).starts_with(".debug")) {
if (Config.CompressionType != DebugCompressionType::None)
CType = Config.CompressionType;
- else if (Config.DecompressDebugSections)
+ else if (Config.getDecompressDebugSections())
CType = DebugCompressionType::None;
}
if (!CType)
@@ -310,7 +310,7 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
// Common and undefined symbols don't make sense as local symbols, and can
// even cause crashes if we localize those, so skip them.
if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF &&
- ((ELFConfig.LocalizeHidden &&
+ ((ELFConfig.getLocalizeHidden() &&
(Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) ||
Config.SymbolsToLocalize.matches(Sym.Name)))
Sym.Binding = STB_LOCAL;
@@ -342,7 +342,7 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
if (Config.SymbolsToWeaken.matches(Sym.Name) && Sym.Binding != STB_LOCAL)
Sym.Binding = STB_WEAK;
- if (Config.Weaken && Sym.Binding != STB_LOCAL &&
+ if (Config.getWeaken() && Sym.Binding != STB_LOCAL &&
Sym.getShndx() != SHN_UNDEF)
Sym.Binding = STB_WEAK;
@@ -361,7 +361,7 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
// The purpose of this loop is to mark symbols referenced by sections
// (like GroupSection or RelocationSection). This way, we know which
// symbols are still 'needed' and which are not.
- if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty() ||
+ if (Config.getStripUnneeded() || !Config.UnneededSymbolsToRemove.empty() ||
!Config.OnlySection.empty() || Config.DiscardMode != DiscardType::None) {
for (SectionBase &Sec : Obj.sections())
Sec.markSymbols();
@@ -369,22 +369,22 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
auto RemoveSymbolsPred = [&](const Symbol &Sym) {
if (Config.SymbolsToKeep.matches(Sym.Name) ||
- (ELFConfig.KeepFileSymbols && Sym.Type == STT_FILE))
+ (ELFConfig.getKeepFileSymbols() && Sym.Type == STT_FILE))
return false;
if (Config.SymbolsToRemove.matches(Sym.Name))
return true;
- if (Config.StripAll || Config.StripAllGNU)
+ if (Config.getStripAll() || Config.getStripAllGNU())
return true;
if (isRequiredByABISymbol(Obj, Sym))
return false;
- if (Config.StripDebug && Sym.Type == STT_FILE)
+ if (Config.getStripDebug() && Sym.Type == STT_FILE)
return true;
- if ((Config.StripUnneeded ||
+ if ((Config.getStripUnneeded() ||
Config.UnneededSymbolsToRemove.matches(Sym.Name)) &&
(!Obj.isRelocatable() || isUnneededSymbol(Sym)))
return true;
@@ -419,17 +419,17 @@ static Error replaceAndRemoveSections(const CommonConfig &Config,
};
}
- if (Config.StripDWO)
+ if (Config.getStripDWO())
RemovePred = [RemovePred](const SectionBase &Sec) {
return isDWOSection(Sec) || RemovePred(Sec);
};
- if (Config.ExtractDWO)
+ if (Config.getExtractDWO())
RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
return onlyKeepDWOPred(Obj, Sec) || RemovePred(Sec);
};
- if (Config.StripAllGNU)
+ if (Config.getStripAllGNU())
RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
if (RemovePred(Sec))
return true;
@@ -447,19 +447,19 @@ static Error replaceAndRemoveSections(const CommonConfig &Config,
return isDebugSection(Sec);
};
- if (Config.StripSections) {
+ if (Config.getStripSections()) {
RemovePred = [RemovePred](const SectionBase &Sec) {
return RemovePred(Sec) || Sec.ParentSegment == nullptr;
};
}
- if (Config.StripDebug || Config.StripUnneeded) {
+ if (Config.getStripDebug() || Config.getStripUnneeded()) {
RemovePred = [RemovePred](const SectionBase &Sec) {
return RemovePred(Sec) || isDebugSection(Sec);
};
}
- if (Config.StripNonAlloc)
+ if (Config.getStripNonAlloc())
RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
if (RemovePred(Sec))
return true;
@@ -468,7 +468,7 @@ static Error replaceAndRemoveSections(const CommonConfig &Config,
return (Sec.Flags & SHF_ALLOC) == 0 && Sec.ParentSegment == nullptr;
};
- if (Config.StripAll)
+ if (Config.getStripAll())
RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
if (RemovePred(Sec))
return true;
@@ -489,7 +489,7 @@ static Error replaceAndRemoveSections(const CommonConfig &Config,
return (Sec.Flags & SHF_ALLOC) == 0;
};
- if (Config.ExtractPartition || Config.ExtractMainPartition) {
+ if (Config.ExtractPartition || Config.getExtractMainPartition()) {
RemovePred = [RemovePred](const SectionBase &Sec) {
if (RemovePred(Sec))
return true;
@@ -537,7 +537,7 @@ static Error replaceAndRemoveSections(const CommonConfig &Config,
// and at least one of those symbols is present
// (equivalently, the updated symbol table is not empty)
// the symbol table and the string table should not be removed.
- if ((!Config.SymbolsToKeep.empty() || ELFConfig.KeepFileSymbols) &&
+ if ((!Config.SymbolsToKeep.empty() || ELFConfig.getKeepFileSymbols()) &&
Obj.SymbolTable && !Obj.SymbolTable->empty()) {
RemovePred = [&Obj, RemovePred](const SectionBase &Sec) {
if (&Sec == Obj.SymbolTable || &Sec == Obj.SymbolTable->getStrTab())
@@ -546,7 +546,7 @@ static Error replaceAndRemoveSections(const CommonConfig &Config,
};
}
- if (Error E = Obj.removeSections(ELFConfig.AllowBrokenLinks, RemovePred))
+ if (Error E = Obj.removeSections(ELFConfig.getAllowBrokenLinks(), RemovePred))
return E;
if (Error E = Obj.compressOrDecompressSections(Config))
@@ -794,9 +794,9 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
Obj.OSABI = Config.OutputArch->OSABI;
}
- if (!Config.SplitDWO.empty() && Config.ExtractDWO) {
+ if (!Config.SplitDWO.empty() && Config.getExtractDWO()) {
return Obj.removeSections(
- ELFConfig.AllowBrokenLinks,
+ ELFConfig.getAllowBrokenLinks(),
[&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); });
}
@@ -903,7 +903,7 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
}
}
- if (Config.OnlyKeepDebug)
+ if (Config.getOnlyKeepDebug())
for (auto &Sec : Obj.sections())
if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE)
Sec.Type = SHT_NOBITS;
@@ -924,7 +924,7 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
Obj.addSection<OwnedDataSection>(Name, Data);
if (Name.starts_with(".note") && Name != ".note.GNU-stack") {
NewSection.Type = SHT_NOTE;
- if (ELFConfig.VerifyNoteSections)
+ if (ELFConfig.getVerifyNoteSections())
return verifyNoteSection(Name, E, Data);
}
return Error::success();
diff --git a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
index 1bca325198e0d..deab0b3e971c5 100644
--- a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
@@ -63,7 +63,7 @@ static Error removeSections(const CommonConfig &Config, Object &Obj) {
};
}
- if (Config.StripAll || Config.StripDebug) {
+ if (Config.getStripAll() || Config.getStripDebug()) {
// Remove all debug sections.
RemovePred = [RemovePred](const std::unique_ptr<Section> &Sec) {
if (Sec->Segname == "__DWARF")
@@ -90,7 +90,7 @@ static void markSymbols(const CommonConfig &Config, Object &Obj) {
(*ISE.Symbol)->Referenced = true;
// --strip-all removes relocations, so their symbols need not be preserved.
- if (Config.StripAll)
+ if (Config.getStripAll())
return;
for (const LoadCommand &LC : Obj.LoadCommands)
@@ -128,7 +128,7 @@ static void updateAndRemoveSymbols(const CommonConfig &Config,
Sym.n_type |= MachO::N_EXT;
if (Sym.isExternalSymbol() && !Sym.isUndefinedSymbol() &&
- (Config.Weaken || Config.SymbolsToWeaken.matches(Sym.Name)))
+ (Config.getWeaken() || Config.SymbolsToWeaken.matches(Sym.Name)))
Sym.n_desc |= MachO::N_WEAK_DEF;
auto I = Config.SymbolsToRename.find(Sym.Name);
@@ -144,12 +144,12 @@ static void updateAndRemoveSymbols(const CommonConfig &Config,
return false;
if (N->n_desc & MachO::REFERENCED_DYNAMICALLY)
return false;
- if (Config.StripAll)
+ if (Config.getStripAll())
return true;
if (Config.DiscardMode == DiscardType::All && !(N->n_type & MachO::N_EXT))
return true;
// This behavior is consistent with cctools' strip.
- if (Config.StripDebug && (N->n_type & MachO::N_STAB))
+ if (Config.getStripDebug() && (N->n_type & MachO::N_STAB))
return true;
// This behavior is consistent with cctools' strip.
if (MachOConfig.StripSwiftSymbols &&
@@ -468,7 +468,7 @@ static Error handleArgs(const CommonConfig &Config,
updateAndRemoveSymbols(Config, MachOConfig, Obj);
- if (Config.StripAll)
+ if (Config.getStripAll())
for (LoadCommand &LC : Obj.LoadCommands)
for (std::unique_ptr<Section> &Sec : LC.Sections)
Sec->Relocations.clear();
@@ -550,7 +550,7 @@ Error objcopy::macho::executeObjcopyOnMachOUniversalBinary(
*NewArchiveMembersOrErr,
(*ArOrErr)->hasSymbolTable() ? SymtabWritingMode::NormalSymtab
: SymtabWritingMode::NoSymtab,
- Kind, Config.getCommonConfig().DeterministicArchives,
+ Kind, Config.getCommonConfig().getDeterministicArchives(),
(*ArOrErr)->isThin());
if (!OutputBufferOrErr)
return OutputBufferOrErr.takeError();
diff --git a/llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp b/llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp
index bf5805464649d..0619c8844a340 100644
--- a/llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp
+++ b/llvm/lib/ObjCopy/wasm/WasmObjcopy.cpp
@@ -60,19 +60,19 @@ static void removeSections(const CommonConfig &Config, Object &Obj) {
};
}
- if (Config.StripDebug) {
+ if (Config.getStripDebug()) {
RemovePred = [RemovePred](const Section &Sec) {
return RemovePred(Sec) || isDebugSection(Sec);
};
}
- if (Config.StripAll) {
+ if (Config.getStripAll()) {
RemovePred = [RemovePred](const Section &Sec) {
return RemovePred(Sec) || !isEngineInterpretedSection(Sec);
};
}
- if (Config.OnlyKeepDebug) {
+ if (Config.getOnlyKeepDebug()) {
RemovePred = [&Config](const Section &Sec) {
// Keep debug sections, unless explicitly requested to remove.
// Remove everything else, including known sections.
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 85c4f69d70dde..9ca5126337abf 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -1452,16 +1452,21 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
}
UuidLoadCmd = Load.Ptr;
} else if (Load.C.cmd == MachO::LC_SEGMENT_64) {
- if ((Err = parseSegmentLoadCommand<MachO::segment_command_64,
- MachO::section_64>(
- *this, Load, Sections, HasPageZeroSegment, I,
- "LC_SEGMENT_64", SizeOfHeaders, Elements)))
+ bool HasPageZero = getHasPageZeroSegment();
+ Err =
+ parseSegmentLoadCommand<MachO::segment_command_64, MachO::section_64>(
+ *this, Load, Sections, HasPageZero, I, "LC_SEGMENT_64",
+ SizeOfHeaders, Elements);
+ setHasPageZeroSegment(HasPageZero);
+ if (Err)
return;
} else if (Load.C.cmd == MachO::LC_SEGMENT) {
- if ((Err = parseSegmentLoadCommand<MachO::segment_command,
- MachO::section>(
- *this, Load, Sections, HasPageZeroSegment, I,
- "LC_SEGMENT", SizeOfHeaders, Elements)))
+ bool HasPageZero = getHasPageZeroSegment();
+ Err = parseSegmentLoadCommand<MachO::segment_command, MachO::section>(
+ *this, Load, Sections, HasPageZero, I, "LC_SEGMENT", SizeOfHeaders,
+ Elements);
+ setHasPageZeroSegment(HasPageZero);
+ if (Err)
return;
} else if (Load.C.cmd == MachO::LC_ID_DYLIB) {
if ((Err = checkDylibIdCommand(*this, Load, I, &DyldIdLoadCmd)))
@@ -3044,13 +3049,13 @@ void ExportEntry::moveToFirst() {
void ExportEntry::moveToEnd() {
Stack.clear();
- Done = true;
+ Stack.setFlag(0, true);
}
bool ExportEntry::operator==(const ExportEntry &Other) const {
// Common case, one at end, other iterating from begin.
- if (Done || Other.Done)
- return (Done == Other.Done);
+ if (Stack.getFlag(0) || Other.Stack.getFlag(0))
+ return Stack.getFlag(0) == Other.Stack.getFlag(0);
// Not equal if different stack sizes.
if (Stack.size() != Other.Stack.size())
return false;
@@ -3333,7 +3338,7 @@ void ExportEntry::moveNext() {
Stack.pop_back();
}
}
- Done = true;
+ Stack.setFlag(0, true);
}
iterator_range<export_iterator>
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index bcb5376eb68b0..db7765efaea78 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -245,21 +245,24 @@ Error DXContainerWriter::writeParts(raw_ostream &OS) {
for (auto El : P.Info->SigInputElements)
PSV.InputElements.push_back(mcdxbc::PSVSignatureElement{
- El.Name, El.Indices, El.StartRow, El.Cols, El.StartCol,
- El.Allocated, El.Kind, El.Type, El.Mode, El.DynamicMask,
- El.Stream});
+ El.Name,
+ SmallVector<uint32_t>(El.Indices.begin(), El.Indices.end()),
+ El.StartRow, El.Cols, El.StartCol, El.getAllocatedFlag(), El.Kind,
+ El.Type, El.Mode, El.DynamicMask, El.Stream});
for (auto El : P.Info->SigOutputElements)
PSV.OutputElements.push_back(mcdxbc::PSVSignatureElement{
- El.Name, El.Indices, El.StartRow, El.Cols, El.StartCol,
- El.Allocated, El.Kind, El.Type, El.Mode, El.DynamicMask,
- El.Stream});
+ El.Name,
+ SmallVector<uint32_t>(El.Indices.begin(), El.Indices.end()),
+ El.StartRow, El.Cols, El.StartCol, El.getAllocatedFlag(), El.Kind,
+ El.Type, El.Mode, El.DynamicMask, El.Stream});
for (auto El : P.Info->SigPatchOrPrimElements)
PSV.PatchOrPrimElements.push_back(mcdxbc::PSVSignatureElement{
- El.Name, El.Indices, El.StartRow, El.Cols, El.StartCol,
- El.Allocated, El.Kind, El.Type, El.Mode, El.DynamicMask,
- El.Stream});
+ El.Name,
+ SmallVector<uint32_t>(El.Indices.begin(), El.Indices.end()),
+ El.StartRow, El.Cols, El.StartCol, El.getAllocatedFlag(), El.Kind,
+ El.Type, El.Mode, El.DynamicMask, El.Stream});
static_assert(PSV.OutputVectorMasks.size() == PSV.InputOutputMap.size());
for (unsigned I = 0; I < PSV.OutputVectorMasks.size(); ++I) {
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index aaf9820c2d668..291cf431eda1a 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -605,7 +605,9 @@ void MappingTraits<DXContainerYAML::SignatureElement>::mapping(
IO.mapRequired("StartRow", El.StartRow);
IO.mapRequired("Cols", El.Cols);
IO.mapRequired("StartCol", El.StartCol);
- IO.mapRequired("Allocated", El.Allocated);
+ bool Allocated = El.isAllocated();
+ IO.mapRequired("Allocated", Allocated);
+ El.setAllocated(Allocated);
IO.mapRequired("Kind", El.Kind);
IO.mapRequired("ComponentType", El.Type);
IO.mapRequired("Interpolation", El.Mode);
diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp
index 7fc9460af418a..160405b935410 100644
--- a/llvm/lib/Option/OptTable.cpp
+++ b/llvm/lib/Option/OptTable.cpp
@@ -76,9 +76,9 @@ OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {}
OptTable::OptTable(const Tables &T, bool IgnoreCase)
: StrTable(T.StrTable), PrefixesTable(T.PrefixesTable),
OptionInfos(T.Infos), InfoExtrasTable(T.InfoExtras),
- IgnoreCase(IgnoreCase), SubCommands(T.SubCommands),
- SubCommandIDsTable(T.SubCommandIDs),
- HelpTextVariantsTable(T.HelpTextVariants) {
+ SubCommands(T.SubCommands), SubCommandIDsTable(T.SubCommandIDs),
+ HelpTextVariantsTable(T.HelpTextVariants),
+ PrefixesUnion(decltype(PrefixesUnion)::withFlags(unsigned(IgnoreCase))) {
// Each prefix set in PrefixesTable starts with its size.
for (unsigned I = 0, E = PrefixesTable.size(); I != E;) {
unsigned Size = PrefixesTable[I++].value();
@@ -371,7 +371,7 @@ std::unique_ptr<Arg> OptTable::parseOneArgGrouped(InputArgList &Args,
// Search for the option which matches Str.
for (; Start != End; ++Start) {
unsigned ArgSize =
- matchOption(StrTable, PrefixesTable, Start, Str, IgnoreCase);
+ matchOption(StrTable, PrefixesTable, Start, Str, getIgnoreCase());
if (!ArgSize)
continue;
@@ -468,8 +468,8 @@ std::unique_ptr<Arg> OptTable::internalParseOneArg(
unsigned ArgSize = 0;
// Scan for first option which is a proper prefix.
for (; Start != End; ++Start)
- if ((ArgSize =
- matchOption(StrTable, PrefixesTable, Start, Str, IgnoreCase)))
+ if ((ArgSize = matchOption(StrTable, PrefixesTable, Start, Str,
+ getIgnoreCase())))
break;
if (Start == End)
break;
@@ -552,7 +552,7 @@ InputArgList OptTable::internalParseArgs(
// In DashDashParsing mode, the first "--" stops option scanning and treats
// all subsequent arguments as positional.
- if (DashDashParsing && Str == "--") {
+ if (getDashDashParsingFlag() && Str == "--") {
while (++Index < End) {
Args.append(new Arg(getOption(InputOptionID), Str, Index,
Args.getArgString(Index)));
@@ -561,10 +561,11 @@ InputArgList OptTable::internalParseArgs(
}
unsigned Prev = Index;
- std::unique_ptr<Arg> A = GroupedShortOptions
- ? parseOneArgGrouped(Args, Index)
- : internalParseOneArg(Args, Index, ExcludeOption);
- assert((Index > Prev || GroupedShortOptions) &&
+ std::unique_ptr<Arg> A =
+ getGroupedShortOptionsFlag()
+ ? parseOneArgGrouped(Args, Index)
+ : internalParseOneArg(Args, Index, ExcludeOption);
+ assert((Index > Prev || getGroupedShortOptionsFlag()) &&
"Parser failed to consume argument.");
// Check for missing argument error.
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index cbb048d15bca2..48ec3e86dd392 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/BuildID.h"
@@ -447,13 +448,14 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
/// ExecutedTestVectorBitmap.
MCDCRecord::TestVectors ExecVectors;
/// Never-executed test vectors
- MCDCRecord::TestVectors NotExecVectors;
+ llvm::SmallVectorWithFlagsFor<MCDCRecord::TestVectors, 1> NotExecVectors;
#ifndef NDEBUG
DenseSet<unsigned> TVIdxs;
#endif
- bool IsVersion11;
+ bool getIsVersion11() const { return NotExecVectors.getFlag(0); }
+ void setIsVersion11(bool Value) { NotExecVectors.setFlag(0, Value); }
public:
MCDCRecordProcessor(const BitVector &Bitmap,
@@ -464,7 +466,9 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
Region(Region), DecisionParams(Region.getDecisionParams()),
Branches(Branches), NumConditions(DecisionParams.NumConditions),
Folded{{BitVector(NumConditions), BitVector(NumConditions)}},
- IndependencePairs(NumConditions), IsVersion11(IsVersion11) {}
+ IndependencePairs(NumConditions),
+ NotExecVectors(
+ decltype(this->NotExecVectors)::withFlags(unsigned(IsVersion11))) {}
private:
// Walk the binary decision diagram and try assigning both false and true to
@@ -488,7 +492,7 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
assert(TVIdxs.insert(NextTVIdx).second && "Duplicate TVIdx");
bool Executed =
- Bitmap[IsVersion11
+ Bitmap[getIsVersion11()
? DecisionParams.BitmapIdx * CHAR_BIT + TV.getIndex()
: DecisionParams.BitmapIdx - NumTestVectors + NextTVIdx];
if (Executed) {
@@ -531,7 +535,7 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
MCDCRecord::TestVectors NewNotExec;
for (const auto &IdxTuple : NotExecVectorIdxs)
NewNotExec.push_back(std::move(NotExecVectors[IdxTuple.Ord]));
- NotExecVectors = std::move(NewNotExec);
+ NotExecVectors.assign(std::move(NewNotExec));
}
public:
@@ -570,7 +574,8 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
findTestVectors();
// Record executed vectors, not-executed vectors, and independence pairs.
- return MCDCRecord(Region, std::move(ExecVectors), std::move(NotExecVectors),
+ return MCDCRecord(Region, MCDCRecord::TestVectors(std::move(ExecVectors)),
+ MCDCRecord::TestVectors(std::move(NotExecVectors)),
std::move(Folded), std::move(PosToID),
std::move(CondLoc));
}
@@ -730,13 +735,14 @@ struct CountedRegionEmitter {
const CoverageMappingRecord &Record;
CounterMappingContext &Ctx;
FunctionRecord &Function;
- bool IsVersion11;
+ bool getIsVersion11() const { return DecisionStack.getFlag(0); }
+ void setIsVersion11(bool Value) { DecisionStack.setFlag(0, Value); }
/// Evaluated Counters.
std::map<Counter, uint64_t> CounterValues;
/// Decisions are nestable.
- SmallVector<DecisionRecord, 1> DecisionStack;
+ llvm::SmallVectorWithFlags<DecisionRecord, 1> DecisionStack;
/// A File pointed by Expansion
struct FileInfo {
@@ -756,7 +762,9 @@ struct CountedRegionEmitter {
CountedRegionEmitter(const CoverageMappingRecord &Record,
CounterMappingContext &Ctx, FunctionRecord &Function,
bool IsVersion11)
- : Record(Record), Ctx(Ctx), Function(Function), IsVersion11(IsVersion11),
+ : Record(Record), Ctx(Ctx), Function(Function),
+ DecisionStack(
+ decltype(this->DecisionStack)::withFlags(unsigned(IsVersion11))),
Files(Record.Filenames.size()) {
// Scan MappingRegions and mark each last index by FileID.
for (auto [I, Region] : enumerate(Record.MappingRegions)) {
@@ -815,7 +823,7 @@ struct CountedRegionEmitter {
if (D.pushBranch(Region)) {
// All Branches have been found in the Decision.
auto RecordOrErr = Ctx.evaluateMCDCRegion(
- *D.DecisionRegion, D.MCDCBranches, IsVersion11);
+ *D.DecisionRegion, D.MCDCBranches, getIsVersion11());
if (!RecordOrErr)
return RecordOrErr.takeError();
diff --git a/llvm/lib/ProfileData/DataAccessProf.cpp b/llvm/lib/ProfileData/DataAccessProf.cpp
index a1e686ba0036b..dd3c005824838 100644
--- a/llvm/lib/ProfileData/DataAccessProf.cpp
+++ b/llvm/lib/ProfileData/DataAccessProf.cpp
@@ -183,7 +183,7 @@ Error DataAccessProfData::serialize(ProfOStream &OS) const {
OS.write((uint64_t)(Records.size()));
for (const auto &[Key, Rec] : Records) {
OS.write(getEncodedIndex(Rec.SymbolID));
- OS.writeByte(Rec.IsStringLiteral);
+ OS.writeByte(Rec.isStringLiteral());
OS.write(Rec.AccessCount);
OS.write(Rec.Locations.size());
for (const auto &Loc : Rec.Locations) {
diff --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp
index 7d0a243d02388..00450b89c8212 100644
--- a/llvm/lib/ProfileData/GCOV.cpp
+++ b/llvm/lib/ProfileData/GCOV.cpp
@@ -14,6 +14,7 @@
#include "llvm/ProfileData/GCOV.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/Debug.h"
@@ -55,9 +56,10 @@ struct Summary {
};
struct LineInfo {
- SmallVector<const GCOVBlock *, 1> blocks;
+ llvm::SmallVectorWithFlags<const GCOVBlock *, 1> blocks;
uint64_t count = 0;
- bool exists = false;
+ bool getExists() const { return blocks.getFlag(0); }
+ void setExists(bool Value) { blocks.setFlag(0, Value); }
};
struct SourceInfo {
@@ -201,14 +203,15 @@ bool GCOVFile::readGCNO(GCOVBuffer &buf) {
buf.de.skip(buf.cursor, pos - buf.cursor.tell());
}
- GCNOInitialized = true;
+ setGCNOInitialized(true);
return true;
}
/// readGCDA - Read GCDA buffer. It is required that readGCDA() can only be
/// called after readGCNO().
bool GCOVFile::readGCDA(GCOVBuffer &buf) {
- assert(GCNOInitialized && "readGCDA() can only be called after readGCNO()");
+ assert(getGCNOInitialized() &&
+ "readGCDA() can only be called after readGCNO()");
if (!buf.readGCDAFormat())
return false;
GCOV::GCOVVersion GCDAVersion;
@@ -523,7 +526,7 @@ GCOVBlock::augmentOneCycle(GCOVBlock *src,
// 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) {
+uint64_t GCOVBlock::getCyclesCount(ArrayRef<const GCOVBlock *> blocks) {
std::vector<std::pair<GCOVBlock *, size_t>> stack;
uint64_t count = 0, d;
for (;;) {
@@ -712,7 +715,7 @@ void Context::collectFunction(GCOVFunction &f, Summary &summary) {
locSource.lines.resize(maxLineNum + 1);
for (uint32_t lineNum : loc.lines) {
LineInfo &line = locSource.lines[lineNum];
- line.exists = true;
+ line.setExists(true);
line.count += b.count;
line.blocks.push_back(&b);
if (f.srcIdx == loc.srcIdx) {
@@ -749,7 +752,7 @@ void Context::collectSourceLine(SourceInfo &si, Summary *summary,
count += GCOVBlock::getCyclesCount(line.blocks);
line.count = count;
- if (line.exists) {
+ if (line.getExists()) {
++summary->lines;
if (line.count != 0)
++summary->linesExec;
@@ -807,7 +810,7 @@ void Context::annotateSource(SourceInfo &si, const GCOVFile &file,
if (options.BranchInfo && lineNum < si.startLineToFunctions.size())
for (const auto *f : si.startLineToFunctions[lineNum])
printFunctionDetails(*f, os);
- if (!line.exists)
+ if (!line.getExists())
os << " -:";
else if (line.count == 0)
os << " #####:";
diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp
index cd78265f5534f..36cfd70285c1c 100644
--- a/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -154,13 +154,14 @@ InstrProfWriter::InstrProfWriter(
uint64_t MaxTemporalProfTraceLength, bool WritePrevVersion,
memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema,
bool MemprofGenerateRandomHotness, unsigned RandomSeed)
- : Sparse(Sparse), MaxTemporalProfTraceLength(MaxTemporalProfTraceLength),
+ : MaxTemporalProfTraceLength(MaxTemporalProfTraceLength),
TemporalProfTraceReservoirSize(TemporalProfTraceReservoirSize),
+ TemporalProfTraces(decltype(this->TemporalProfTraces)::withFlags(
+ unsigned(Sparse) | (unsigned(WritePrevVersion) << 1) |
+ (unsigned(MemProfFullSchema) << 2) |
+ (unsigned(MemprofGenerateRandomHotness) << 3))),
InfoObj(new InstrProfRecordWriterTrait()),
- WritePrevVersion(WritePrevVersion),
- MemProfVersionRequested(MemProfVersionRequested),
- MemProfFullSchema(MemProfFullSchema),
- MemprofGenerateRandomHotness(MemprofGenerateRandomHotness) {
+ MemProfVersionRequested(MemProfVersionRequested) {
if (RandomSeed)
RNG.seed(RandomSeed);
}
@@ -172,7 +173,7 @@ void InstrProfWriter::setValueProfDataEndianness(llvm::endianness Endianness) {
InfoObj->ValueProfDataEndianness = Endianness;
}
-void InstrProfWriter::setOutputSparse(bool Sparse) { this->Sparse = Sparse; }
+void InstrProfWriter::setOutputSparse(bool Sparse) { this->setSparse(Sparse); }
void InstrProfWriter::addRecord(NamedInstrProfRecord &&I, uint64_t Weight,
function_ref<void(Error)> Warn) {
@@ -245,7 +246,7 @@ void InstrProfWriter::addMemProfRecord(
// Provoke random hotness values if requested. We specify the lifetime access
// density and lifetime length that will result in a cold or not cold hotness.
// See the logic in getAllocType() in Analysis/MemoryProfileInfo.cpp.
- if (MemprofGenerateRandomHotness) {
+ if (getMemprofGenerateRandomHotness()) {
for (auto &Alloc : NewRecord.AllocSites) {
// To get a not cold context, set the lifetime access density to the
// maximum value and the lifetime to 0.
@@ -331,7 +332,7 @@ bool InstrProfWriter::addMemProfData(memprof::IndexedMemProfData Incoming,
return false;
// Add one record at a time if randomization is requested.
- if (MemProfData.Records.empty() && !MemprofGenerateRandomHotness) {
+ if (MemProfData.Records.empty() && !getMemprofGenerateRandomHotness()) {
// Need to manually add each record to the builder, which is otherwise done
// in addMemProfRecord.
for (const auto &[GUID, Record] : Incoming.Records)
@@ -356,6 +357,12 @@ void InstrProfWriter::addDataAccessProfData(
void InstrProfWriter::addTemporalProfileTraces(
SmallVectorImpl<TemporalProfTraceTy> &SrcTraces, uint64_t SrcStreamSize) {
+ addTemporalProfileTracesImpl(SrcTraces, SrcStreamSize);
+}
+
+template <typename TraceVectorT>
+void InstrProfWriter::addTemporalProfileTracesImpl(TraceVectorT &SrcTraces,
+ uint64_t SrcStreamSize) {
if (TemporalProfTraces.size() > TemporalProfTraceReservoirSize)
TemporalProfTraces.truncate(TemporalProfTraceReservoirSize);
for (auto &Trace : SrcTraces)
@@ -394,8 +401,8 @@ void InstrProfWriter::mergeRecordsFromWriter(InstrProfWriter &&IPW,
for (auto &I : IPW.BinaryIds)
addBinaryIds(I);
- addTemporalProfileTraces(IPW.TemporalProfTraces,
- IPW.TemporalProfTraceStreamSize);
+ addTemporalProfileTracesImpl(IPW.TemporalProfTraces,
+ IPW.TemporalProfTraceStreamSize);
MemProfData.Frames.reserve(IPW.MemProfData.Frames.size());
for (auto &[FrameId, Frame] : IPW.MemProfData.Frames) {
@@ -418,7 +425,7 @@ void InstrProfWriter::mergeRecordsFromWriter(InstrProfWriter &&IPW,
}
bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) {
- if (!Sparse)
+ if (!getSparse())
return true;
for (const auto &Func : PD) {
const InstrProfRecord &IPR = Func.second;
@@ -548,7 +555,7 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
InfoObj->SummaryBuilder = &ISB;
InstrProfSummaryBuilder CSISB(ProfileSummaryBuilder::DefaultCutoffs);
InfoObj->CSSummaryBuilder = &CSISB;
- InfoObj->WritePrevVersion = WritePrevVersion;
+ InfoObj->WritePrevVersion = getWritePrevVersion();
// Populate the hash table generator.
SmallVector<std::pair<StringRef, const ProfilingData *>> OrderedData;
@@ -561,7 +568,7 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
// Write the header.
IndexedInstrProf::Header Header;
- Header.Version = WritePrevVersion
+ Header.Version = getWritePrevVersion()
? IndexedInstrProf::ProfVersion::Version11
: IndexedInstrProf::ProfVersion::CurrentVersion;
// The WritePrevVersion handling will either need to be removed or updated
@@ -588,7 +595,7 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
Header.Version |= VARIANT_MASK_TEMPORAL_PROF;
const uint64_t BackPatchStartOffset =
- writeHeader(Header, WritePrevVersion, OS);
+ writeHeader(Header, getWritePrevVersion(), OS);
// Reserve space to write profile summary data.
uint32_t NumEntries = ProfileSummaryBuilder::DefaultCutoffs.size();
@@ -614,9 +621,10 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
if (static_cast<bool>(ProfileKind & InstrProfKind::MemProf)) {
MemProfSectionStart = OS.tell();
- if (auto E = writeMemProf(
- OS, MemProfData, MemProfVersionRequested, MemProfFullSchema,
- std::move(DataAccessProfileData), MemProfSumBuilder.getSummary()))
+ if (auto E = writeMemProf(OS, MemProfData, MemProfVersionRequested,
+ getMemProfFullSchemaFlag(),
+ std::move(DataAccessProfileData),
+ MemProfSumBuilder.getSummary()))
return E;
}
@@ -626,7 +634,7 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
uint64_t VTableNamesSectionStart = OS.tell();
- if (!WritePrevVersion)
+ if (!getWritePrevVersion())
if (Error E = writeVTableNames(OS))
return E;
@@ -664,7 +672,7 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
SmallVector<uint64_t, 8> HeaderOffsets = {HashTableStart, MemProfSectionStart,
BinaryIdSectionStart,
TemporalProfTracesSectionStart};
- if (!WritePrevVersion)
+ if (!getWritePrevVersion())
HeaderOffsets.push_back(VTableNamesSectionStart);
PatchItem PatchItems[] = {
diff --git a/llvm/lib/ProfileData/MemProfReader.cpp b/llvm/lib/ProfileData/MemProfReader.cpp
index c6f7295c3422c..6bffe0ed1096b 100644
--- a/llvm/lib/ProfileData/MemProfReader.cpp
+++ b/llvm/lib/ProfileData/MemProfReader.cpp
@@ -638,7 +638,7 @@ Error RawMemProfReader::symbolizeAndFilterStackFrames(
// instead of adding it to the frame object directly to reduce memory
// overhead. This is because there can be many unique frames,
// particularly for callsite frames.
- if (KeepSymbolName) {
+ if (getKeepSymbolName()) {
StringRef CanonicalName =
sampleprof::FunctionSamples::getCanonicalFnName(
DIFrame.FunctionName);
@@ -732,7 +732,9 @@ Error RawMemProfReader::readRawProfile(
// profiles in this binary file.
const llvm::SmallVector<SegmentEntry> Entries =
readSegmentEntries(Next + Header->SegmentOffset);
- if (!SegmentInfo.empty() && SegmentInfo != Entries) {
+ if (!SegmentInfo.empty() &&
+ (llvm::ArrayRef<llvm::memprof::SegmentEntry>(SegmentInfo) !=
+ llvm::ArrayRef<llvm::memprof::SegmentEntry>(Entries))) {
// We do not expect segment information to change when deserializing from
// the same binary profile file. This can happen if dynamic libraries are
// loaded/unloaded between profile dumping.
@@ -811,7 +813,7 @@ Error RawMemProfReader::readNextRecord(
// true. This is useful for debugging and testing.
auto IdToFrameCallback = [this](const FrameId Id) {
Frame F = this->idToFrame(Id);
- if (!this->KeepSymbolName)
+ if (!this->getKeepSymbolName())
return F;
auto Iter = this->GuidToSymbolName.find(F.Function);
assert(Iter != this->GuidToSymbolName.end());
diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp
index d6a6aef1c59f9..9e8084e70cbe8 100644
--- a/llvm/lib/ProfileData/SampleProfWriter.cpp
+++ b/llvm/lib/ProfileData/SampleProfWriter.cpp
@@ -278,10 +278,10 @@ SampleProfileWriterExtBinaryBase::writeSample(const FunctionSamples &S) {
std::error_code
SampleProfileWriterExtBinaryBase::writeFuncOffsetTable(SecType Type,
bool IsNested) {
- if (UseMD5IndexedTables) {
+ if (getUseMD5IndexedTablesFlag()) {
// Eytzinger layout requires MD5 representation and does not support
// multi-context Context-Sensitive profiles.
- if (!UseMD5 || FunctionSamples::ProfileIsCS)
+ if (!getUseMD5Flag() || FunctionSamples::ProfileIsCS)
return sampleprof_error::unsupported_writing_format;
return writeEytzingerFuncOffsetTable(Type, IsNested);
}
@@ -430,7 +430,7 @@ stabilizeTable(MapVector<KeyT, ValT> &Table) {
}
std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() {
- if (!UseMD5)
+ if (!getUseMD5Flag())
return SampleProfileWriterBinary::writeNameTable();
auto &OS = *OutputStream;
@@ -456,7 +456,7 @@ std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection(
// so compiler won't strip the suffix during profile matching after
// seeing the flag in the profile.
// Original names are unavailable if using MD5, so this option has no use.
- if (!UseMD5) {
+ if (!getUseMD5Flag()) {
for (const auto &I : NameTable) {
if (I.first.stringRef().contains(FunctionSamples::UniqSuffix)) {
addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagUniqSuffix);
@@ -465,7 +465,7 @@ std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection(
}
}
- if (UseMD5 && UseMD5IndexedTables) {
+ if (getUseMD5Flag() && getUseMD5IndexedTablesFlag()) {
// Eytzinger name tables do not support CSSPGO profiles
// (FunctionSamples::ProfileIsCS).
if (FunctionSamples::ProfileIsCS)
@@ -596,7 +596,7 @@ std::error_code SampleProfileWriterExtBinaryBase::writeCSNameTableSection() {
std::error_code
SampleProfileWriterExtBinaryBase::writeProfileSymbolListSection() {
- if (UseMD5ProfSymList)
+ if (getUseMD5ProfSymList())
return writeMD5ProfileSymbolListSection();
return writeStringBasedProfileSymbolListSection();
}
@@ -658,9 +658,9 @@ std::error_code SampleProfileWriterExtBinaryBase::writeOneSection(
if (Type == SecProfSummary && ExtBinaryWriteVTableTypeProf)
addSectionFlag(SecProfSummary,
SecProfSummaryFlags::SecFlagHasVTableTypeProf);
- if (Type == SecProfileSymbolList && UseMD5ProfSymList)
+ if (Type == SecProfileSymbolList && getUseMD5ProfSymList())
addSectionFlag(SecProfileSymbolList, SecProfileSymbolListFlags::SecFlagMD5);
- if (Type == SecNameTable && UseMD5IndexedTables && UseMD5)
+ if (Type == SecNameTable && getUseMD5IndexedTablesFlag() && getUseMD5Flag())
addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagEytzinger);
uint64_t SectionStart = markSectionStart(Type, LayoutIdx);
diff --git a/llvm/lib/Support/DebugCounter.cpp b/llvm/lib/Support/DebugCounter.cpp
index d9786838aba23..f21554a2acfd2 100644
--- a/llvm/lib/Support/DebugCounter.cpp
+++ b/llvm/lib/Support/DebugCounter.cpp
@@ -138,8 +138,8 @@ void DebugCounter::push_back(const std::string &Val) {
});
exit(1);
}
- Counter->Chunks = std::move(*ExpectedChunks);
- Counter->Active = Counter->IsSet = true;
+ Counter->Chunks.assign(std::move(*ExpectedChunks));
+ Counter->setActive(Counter->setIsSet(true));
}
void DebugCounter::print(raw_ostream &OS) const {
@@ -183,7 +183,7 @@ bool DebugCounter::handleCounterIncrement(CounterInfo &Info) {
bool DebugCounter::shouldExecuteImpl(CounterInfo &Counter) {
auto &Us = instance();
bool Res = Us.handleCounterIncrement(Counter);
- if (Us.ShouldPrintCounterQueries && Counter.IsSet) {
+ if (Us.ShouldPrintCounterQueries && Counter.getIsSet()) {
dbgs() << "DebugCounter " << Counter.Name << "=" << (Counter.Count - 1)
<< (Res ? " execute" : " skip") << "\n";
}
diff --git a/llvm/lib/Support/GlobPattern.cpp b/llvm/lib/Support/GlobPattern.cpp
index 9a6ce774e4150..dc6bc4dddbc3f 100644
--- a/llvm/lib/Support/GlobPattern.cpp
+++ b/llvm/lib/Support/GlobPattern.cpp
@@ -186,7 +186,7 @@ Expected<GlobPattern> GlobPattern::create(StringRef S,
std::optional<size_t> MaxSubPatterns,
bool SlashAgnostic) {
GlobPattern Pat;
- Pat.SlashAgnostic = SlashAgnostic;
+ Pat.SubGlobs.setFlag(0, SlashAgnostic);
Pat.Pattern = S;
const char *PrefixMetas =
@@ -244,7 +244,7 @@ std::optional<std::string> GlobPattern::asLiteral() const {
// In slash-agnostic mode '/' and '\\' match each other, so a pattern holding
// either matches more than one string. A pattern with no sub-pattern cannot
// reach here holding one, as both are prefix metacharacters in that mode.
- if (SlashAgnostic &&
+ if (SubGlobs.getFlag(0) &&
StringRef(Literal).find_first_of("/\\") != StringRef::npos)
return std::nullopt;
@@ -287,7 +287,7 @@ GlobPattern::SubGlobPattern::create(StringRef S, bool SlashAgnostic) {
return make_error<StringError>("invalid glob pattern, stray '\\'",
errc::invalid_argument);
} else if (S[I] == '*' || S[I] == '?') {
- Pat.HasWildcard = true;
+ Pat.Pat.setFlag(0, true);
}
}
return Pat;
@@ -295,7 +295,7 @@ GlobPattern::SubGlobPattern::create(StringRef S, bool SlashAgnostic) {
StringRef GlobPattern::longest_substr() const {
return maxPlainSubstring(Pattern.drop_front(PrefixSize).drop_back(SuffixSize),
- SlashAgnostic);
+ SubGlobs.getFlag(0));
}
bool GlobPattern::match(StringRef S) const {
@@ -306,7 +306,7 @@ bool GlobPattern::match(StringRef S) const {
if (SubGlobs.empty() && S.empty())
return true;
for (auto &Glob : SubGlobs)
- if (Glob.match(S, SlashAgnostic))
+ if (Glob.match(S, SubGlobs.getFlag(0)))
return true;
return false;
}
diff --git a/llvm/lib/Support/LSP/Transport.cpp b/llvm/lib/Support/LSP/Transport.cpp
index e79ca679878d0..94e4b743f155a 100644
--- a/llvm/lib/Support/LSP/Transport.cpp
+++ b/llvm/lib/Support/LSP/Transport.cpp
@@ -244,13 +244,15 @@ llvm::Error JSONTransport::run(MessageHandler &Handler) {
}
void JSONTransport::sendMessage(llvm::json::Value Msg) {
- OutputBuffer.clear();
- llvm::raw_svector_ostream os(OutputBuffer);
- os << llvm::formatv(PrettyOutput ? "{0:2}\n" : "{0}", Msg);
- Out << "Content-Length: " << OutputBuffer.size() << "\r\n\r\n"
- << OutputBuffer;
+ SmallVector<char, 0> Buffer;
+ Buffer = std::move(OutputBuffer);
+ Buffer.clear();
+ llvm::raw_svector_ostream os(Buffer);
+ os << llvm::formatv(getPrettyOutput() ? "{0:2}\n" : "{0}", Msg);
+ Out << "Content-Length: " << Buffer.size() << "\r\n\r\n" << Buffer;
Out.flush();
- Logger::debug(">>> {0}\n", OutputBuffer);
+ Logger::debug(">>> {0}\n", Buffer);
+ OutputBuffer.assign(std::move(Buffer));
}
bool JSONTransport::handleMessage(llvm::json::Value Msg,
diff --git a/llvm/lib/Support/SuffixTree.cpp b/llvm/lib/Support/SuffixTree.cpp
index a31287836e860..8873b58e646bc 100644
--- a/llvm/lib/Support/SuffixTree.cpp
+++ b/llvm/lib/Support/SuffixTree.cpp
@@ -329,7 +329,7 @@ void SuffixTree::RepeatedSubstringIterator::advance() {
continue;
// Collect leaf children or leaf descendants by OutlinerLeafDescendants.
- if (OutlinerLeafDescendants) {
+ if (getOutlinerLeafDescendants()) {
for (unsigned I = Curr->getLeftLeafIdx(); I <= Curr->getRightLeafIdx();
++I)
RepeatedSubstringStarts.push_back(LeafNodes[I]->getSuffixIdx());
diff --git a/llvm/lib/Support/YAMLParser.cpp b/llvm/lib/Support/YAMLParser.cpp
index 2ee104aa2be60..1da4864f41a58 100644
--- a/llvm/lib/Support/YAMLParser.cpp
+++ b/llvm/lib/Support/YAMLParser.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -259,7 +260,8 @@ class Scanner {
void printError(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Message,
ArrayRef<SMRange> Ranges = {}) {
- SM.PrintMessage(Loc, Kind, Message, Ranges, /* FixIts= */ {}, ShowColors);
+ SM.PrintMessage(Loc, Kind, Message, Ranges, /* FixIts= */ {},
+ getShowColors());
}
void setError(const Twine &Message, StringRef::iterator Position) {
@@ -272,15 +274,13 @@ class Scanner {
// Don't print out more errors after the first one we encounter. The rest
// are just the result of the first, and have no meaning.
- if (!Failed)
+ if (!getFailed())
printError(SMLoc::getFromPointer(Position), SourceMgr::DK_Error, Message);
- Failed = true;
+ setFailed(true);
}
/// Returns true if an error occurred while parsing.
- bool failed() {
- return Failed;
- }
+ bool failed() { return getFailed(); }
private:
void init(MemoryBufferRef Buffer);
@@ -543,20 +543,27 @@ class Scanner {
unsigned FlowLevel;
/// Are we at the start of the stream?
- bool IsStartOfStream;
+ bool getIsStartOfStream() const { return SimpleKeys.getFlag(0); }
+ void setIsStartOfStream(bool Value) { SimpleKeys.setFlag(0, Value); }
/// Can the next token be the start of a simple key?
- bool IsSimpleKeyAllowed;
+ bool getIsSimpleKeyAllowed() const { return SimpleKeys.getFlag(1); }
+ void setIsSimpleKeyAllowed(bool Value) { SimpleKeys.setFlag(1, Value); }
/// Can the next token be a value indicator even if it does not have a
/// trailing space?
- bool IsAdjacentValueAllowedInFlow;
+ bool getIsAdjacentValueAllowedInFlow() const { return SimpleKeys.getFlag(2); }
+ void setIsAdjacentValueAllowedInFlow(bool Value) {
+ SimpleKeys.setFlag(2, Value);
+ }
/// True if an error has occurred.
- bool Failed;
+ bool getFailed() const { return SimpleKeys.getFlag(3); }
+ void setFailed(bool Value) { SimpleKeys.setFlag(3, Value); }
/// Should colors be used when printing out the diagnostic messages?
- bool ShowColors;
+ bool getShowColors() const { return Indents.getFlag(0); }
+ void setShowColors(bool Value) { Indents.setFlag(0, Value); }
/// Queue of tokens. This is required to queue up tokens while looking
/// for the end of a simple key. And for cases where a single character
@@ -564,10 +571,10 @@ class Scanner {
TokenQueueT TokenQueue;
/// Indentation levels.
- SmallVector<int, 4> Indents;
+ llvm::SmallVectorWithFlags<int, 4> Indents;
/// Potential simple keys.
- SmallVector<SimpleKey, 4> SimpleKeys;
+ llvm::SmallVectorWithFlags<SimpleKey, 4, 4> SimpleKeys;
std::error_code *EC;
};
@@ -856,13 +863,16 @@ std::optional<bool> yaml::parseBool(StringRef S) {
Scanner::Scanner(StringRef Input, SourceMgr &sm, bool ShowColors,
std::error_code *EC)
- : SM(sm), ShowColors(ShowColors), EC(EC) {
+ : SM(sm), Indents(decltype(this->Indents)::withFlags(unsigned(ShowColors))),
+ EC(EC) {
init(MemoryBufferRef(Input, "YAML"));
}
Scanner::Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors,
std::error_code *EC)
- : SM(SM_), ShowColors(ShowColors), EC(EC) {
+ : SM(SM_),
+ Indents(decltype(this->Indents)::withFlags(unsigned(ShowColors))),
+ EC(EC) {
init(Buffer);
}
@@ -874,10 +884,10 @@ void Scanner::init(MemoryBufferRef Buffer) {
Column = 0;
Line = 0;
FlowLevel = 0;
- IsStartOfStream = true;
- IsSimpleKeyAllowed = true;
- IsAdjacentValueAllowedInFlow = false;
- Failed = false;
+ setIsStartOfStream(true);
+ setIsSimpleKeyAllowed(true);
+ setIsAdjacentValueAllowedInFlow(false);
+ setFailed(false);
std::unique_ptr<MemoryBuffer> InputBufferOwner =
MemoryBuffer::getMemBuffer(Buffer, /*RequiresNullTerminator=*/false);
SM.AddNewSourceBuffer(std::move(InputBufferOwner), SMLoc());
@@ -1086,7 +1096,7 @@ bool Scanner::consumeLineBreakIfPresent() {
void Scanner::saveSimpleKeyCandidate( TokenQueueT::iterator Tok
, unsigned AtColumn
, bool IsRequired) {
- if (IsSimpleKeyAllowed) {
+ if (getIsSimpleKeyAllowed()) {
SimpleKey SK;
SK.Tok = Tok;
SK.Line = Line;
@@ -1180,12 +1190,12 @@ void Scanner::scanToNextToken() {
Column = 0;
// New lines may start a simple key.
if (!FlowLevel)
- IsSimpleKeyAllowed = true;
+ setIsSimpleKeyAllowed(true);
}
}
bool Scanner::scanStreamStart() {
- IsStartOfStream = false;
+ setIsStartOfStream(false);
EncodingInfo EI = getUnicodeEncoding(currentInput());
@@ -1206,8 +1216,8 @@ bool Scanner::scanStreamEnd() {
unrollIndent(-1);
SimpleKeys.clear();
- IsSimpleKeyAllowed = false;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(false);
+ setIsAdjacentValueAllowedInFlow(false);
Token T;
T.Kind = Token::TK_StreamEnd;
@@ -1220,8 +1230,8 @@ bool Scanner::scanDirective() {
// Reset the indentation level.
unrollIndent(-1);
SimpleKeys.clear();
- IsSimpleKeyAllowed = false;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(false);
+ setIsAdjacentValueAllowedInFlow(false);
StringRef::iterator Start = Current;
consume('%');
@@ -1252,8 +1262,8 @@ bool Scanner::scanDirective() {
bool Scanner::scanDocumentIndicator(bool IsStart) {
unrollIndent(-1);
SimpleKeys.clear();
- IsSimpleKeyAllowed = false;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(false);
+ setIsAdjacentValueAllowedInFlow(false);
Token T;
T.Kind = IsStart ? Token::TK_DocumentStart : Token::TK_DocumentEnd;
@@ -1275,17 +1285,17 @@ bool Scanner::scanFlowCollectionStart(bool IsSequence) {
saveSimpleKeyCandidate(--TokenQueue.end(), Column - 1, false);
// And may also be followed by a simple key.
- IsSimpleKeyAllowed = true;
+ setIsSimpleKeyAllowed(true);
// Adjacent values are allowed in flows only after JSON-style keys.
- IsAdjacentValueAllowedInFlow = false;
+ setIsAdjacentValueAllowedInFlow(false);
++FlowLevel;
return true;
}
bool Scanner::scanFlowCollectionEnd(bool IsSequence) {
removeSimpleKeyCandidatesOnFlowLevel(FlowLevel);
- IsSimpleKeyAllowed = false;
- IsAdjacentValueAllowedInFlow = true;
+ setIsSimpleKeyAllowed(false);
+ setIsAdjacentValueAllowedInFlow(true);
Token T;
T.Kind = IsSequence ? Token::TK_FlowSequenceEnd
: Token::TK_FlowMappingEnd;
@@ -1299,8 +1309,8 @@ bool Scanner::scanFlowCollectionEnd(bool IsSequence) {
bool Scanner::scanFlowEntry() {
removeSimpleKeyCandidatesOnFlowLevel(FlowLevel);
- IsSimpleKeyAllowed = true;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(true);
+ setIsAdjacentValueAllowedInFlow(false);
Token T;
T.Kind = Token::TK_FlowEntry;
T.Range = StringRef(Current, 1);
@@ -1312,8 +1322,8 @@ bool Scanner::scanFlowEntry() {
bool Scanner::scanBlockEntry() {
rollIndent(Column, Token::TK_BlockSequenceStart, TokenQueue.end());
removeSimpleKeyCandidatesOnFlowLevel(FlowLevel);
- IsSimpleKeyAllowed = true;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(true);
+ setIsAdjacentValueAllowedInFlow(false);
Token T;
T.Kind = Token::TK_BlockEntry;
T.Range = StringRef(Current, 1);
@@ -1327,8 +1337,8 @@ bool Scanner::scanKey() {
rollIndent(Column, Token::TK_BlockMappingStart, TokenQueue.end());
removeSimpleKeyCandidatesOnFlowLevel(FlowLevel);
- IsSimpleKeyAllowed = !FlowLevel;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(!FlowLevel);
+ setIsAdjacentValueAllowedInFlow(false);
Token T;
T.Kind = Token::TK_Key;
@@ -1352,7 +1362,7 @@ bool Scanner::scanValue() {
break;
}
if (i == e) {
- Failed = true;
+ setFailed(true);
return false;
}
i = TokenQueue.insert(i, T);
@@ -1360,13 +1370,13 @@ bool Scanner::scanValue() {
// We may also need to add a Block-Mapping-Start token.
rollIndent(SK.Column, Token::TK_BlockMappingStart, i);
- IsSimpleKeyAllowed = false;
+ setIsSimpleKeyAllowed(false);
} else {
if (!FlowLevel)
rollIndent(Column, Token::TK_BlockMappingStart, TokenQueue.end());
- IsSimpleKeyAllowed = !FlowLevel;
+ setIsSimpleKeyAllowed(!FlowLevel);
}
- IsAdjacentValueAllowedInFlow = false;
+ setIsAdjacentValueAllowedInFlow(false);
Token T;
T.Kind = Token::TK_Value;
@@ -1447,8 +1457,8 @@ bool Scanner::scanFlowScalar(bool IsDoubleQuoted) {
saveSimpleKeyCandidate(--TokenQueue.end(), ColStart, false);
- IsSimpleKeyAllowed = false;
- IsAdjacentValueAllowedInFlow = true;
+ setIsSimpleKeyAllowed(false);
+ setIsAdjacentValueAllowedInFlow(true);
return true;
}
@@ -1515,8 +1525,8 @@ bool Scanner::scanPlainScalar() {
// Plain scalars can be simple keys.
saveSimpleKeyCandidate(--TokenQueue.end(), ColStart, false);
- IsSimpleKeyAllowed = false;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(false);
+ setIsAdjacentValueAllowedInFlow(false);
return true;
}
@@ -1551,8 +1561,8 @@ bool Scanner::scanAliasOrAnchor(bool IsAlias) {
// Alias and anchors can be simple keys.
saveSimpleKeyCandidate(--TokenQueue.end(), ColStart, false);
- IsSimpleKeyAllowed = false;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(false);
+ setIsAdjacentValueAllowedInFlow(false);
return true;
}
@@ -1784,8 +1794,8 @@ bool Scanner::scanBlockScalar(bool IsLiteral) {
// New lines may start a simple key.
if (!FlowLevel)
- IsSimpleKeyAllowed = true;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(true);
+ setIsAdjacentValueAllowedInFlow(false);
Token T;
T.Kind = Token::TK_BlockScalar;
@@ -1818,14 +1828,14 @@ bool Scanner::scanTag() {
// Tags can be simple keys.
saveSimpleKeyCandidate(--TokenQueue.end(), ColStart, false);
- IsSimpleKeyAllowed = false;
- IsAdjacentValueAllowedInFlow = false;
+ setIsSimpleKeyAllowed(false);
+ setIsAdjacentValueAllowedInFlow(false);
return true;
}
bool Scanner::fetchMoreTokens() {
- if (IsStartOfStream)
+ if (getIsStartOfStream())
return scanStreamStart();
scanToNextToken();
@@ -1876,7 +1886,7 @@ bool Scanner::fetchMoreTokens() {
return scanKey();
if (*Current == ':' &&
- (!isPlainSafeNonBlank(Current + 1) || IsAdjacentValueAllowedInFlow))
+ (!isPlainSafeNonBlank(Current + 1) || getIsAdjacentValueAllowedInFlow()))
return scanValue();
if (*Current == '*')
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index bbddfc8b4e72e..d83ca7be79f3e 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -769,7 +769,7 @@ const Record *TGParser::ParseClassID() {
Lex.getCurStrVal() + "'");
else
TokError(Msg);
- } else if (TrackReferenceLocs) {
+ } else if (getTrackReferenceLocs()) {
Result->appendReferenceLoc(Lex.getLocRange());
}
@@ -1197,7 +1197,7 @@ const RecTy *TGParser::ParseType() {
const Init *TGParser::ParseIDValue(Record *CurRec, const StringInit *Name,
SMRange NameLoc, IDParseMode Mode) {
if (const Init *I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,
- TrackReferenceLocs))
+ getTrackReferenceLocs()))
return I;
if (Mode == ParseNameMode)
@@ -1205,7 +1205,7 @@ const Init *TGParser::ParseIDValue(Record *CurRec, const StringInit *Name,
if (const Init *I = Records.getGlobal(Name->getValue())) {
// Add a reference to the global if it's a record.
- if (TrackReferenceLocs) {
+ if (getTrackReferenceLocs()) {
if (const auto *Def = dyn_cast<DefInit>(I))
Def->getDef()->appendReferenceLoc(NameLoc);
}
@@ -3045,7 +3045,7 @@ const Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
if (resolveArguments(Class, Args, NameLoc.Start))
return nullptr;
- if (TrackReferenceLocs)
+ if (getTrackReferenceLocs())
Class->appendReferenceLoc(NameLoc);
return VarDefInit::get(NameLoc.Start, Class, Args)->Fold();
}
@@ -3334,7 +3334,7 @@ const Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
}
// Add a reference to this field if we know the record class.
- if (TrackReferenceLocs) {
+ if (getTrackReferenceLocs()) {
if (const auto *DI = dyn_cast<DefInit>(Result)) {
DI->getDef()->appendValueReferenceLoc(FieldName, FieldNameLoc);
} else if (const auto *TI = dyn_cast<TypedInit>(Result)) {
@@ -4391,7 +4391,7 @@ bool TGParser::ParseClass() {
if (ParseObjectBody(CurRec))
return true;
- if (!NoWarnOnUnusedTemplateArgs)
+ if (!getNoWarnOnUnusedTemplateArgs())
CurRec->checkUnusedTemplateArgs();
PopScope(ClassScope);
@@ -4590,7 +4590,7 @@ bool TGParser::ParseMultiClass() {
}
}
- if (!NoWarnOnUnusedTemplateArgs)
+ if (!getNoWarnOnUnusedTemplateArgs())
CurMultiClass->Rec.checkUnusedTemplateArgs();
PopScope(MulticlassScope);
diff --git a/llvm/lib/TableGen/TGParser.h b/llvm/lib/TableGen/TGParser.h
index 31b59628a6cac..7f0598f822ae7 100644
--- a/llvm/lib/TableGen/TGParser.h
+++ b/llvm/lib/TableGen/TGParser.h
@@ -14,6 +14,7 @@
#define LLVM_LIB_TABLEGEN_TGPARSER_H
#include "TGLexer.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include <map>
@@ -164,7 +165,7 @@ class TGParser {
///
std::vector<std::unique_ptr<ForeachLoop>> Loops;
- SmallVector<DefsetRecord *, 2> Defsets;
+ llvm::SmallVectorWithFlags<DefsetRecord *, 2, 2> Defsets;
/// CurMultiClass - If we are parsing a 'multiclass' definition, this is the
/// current value.
@@ -187,16 +188,19 @@ class TGParser {
// exist.
};
- bool NoWarnOnUnusedTemplateArgs = false;
- bool TrackReferenceLocs = false;
+ bool getNoWarnOnUnusedTemplateArgs() const { return Defsets.getFlag(0); }
+ void setNoWarnOnUnusedTemplateArgs(bool Value) { Defsets.setFlag(0, Value); }
+ bool getTrackReferenceLocs() const { return Defsets.getFlag(1); }
+ void setTrackReferenceLocs(bool Value) { Defsets.setFlag(1, Value); }
public:
TGParser(SourceMgr &SM, ArrayRef<std::string> Macros, RecordKeeper &records,
const bool NoWarnOnUnusedTemplateArgs = false,
const bool TrackReferenceLocs = false)
- : Lex(SM, Macros), CurMultiClass(nullptr), Records(records),
- NoWarnOnUnusedTemplateArgs(NoWarnOnUnusedTemplateArgs),
- TrackReferenceLocs(TrackReferenceLocs) {}
+ : Lex(SM, Macros), Defsets(decltype(Defsets)::withFlags(
+ unsigned(NoWarnOnUnusedTemplateArgs) |
+ (unsigned(TrackReferenceLocs) << 1))),
+ CurMultiClass(nullptr), Records(records) {}
/// ParseFile - Main entrypoint for parsing a tblgen file. These parser
/// routines return true on error, or false on success.
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index e3257af644550..e81876aa2e512 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9320,8 +9320,8 @@ SDValue AArch64TargetLowering::lowerEHPadEntry(SDValue Chain, SDLoc const &DL,
SDValue AArch64TargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
const Function &F = MF.getFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -9987,8 +9987,8 @@ static void analyzeCallOperands(const AArch64TargetLowering &TLI,
CCState &CCInfo) {
const SelectionDAG &DAG = CLI.DAG;
CallingConv::ID CalleeCC = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
- const SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
+ bool IsVarArg = CLI.getIsVarArg();
+ const auto &Outs = CLI.Outs;
bool IsCalleeWin64 = Subtarget->isCallingConvWin64(CalleeCC, IsVarArg);
// For Arm64EC thunks, allocate 32 extra bytes at the bottom of the stack
@@ -10061,10 +10061,10 @@ bool AArch64TargetLowering::isEligibleForTailCallOptimization(
return false;
SDValue Callee = CLI.Callee;
- bool IsVarArg = CLI.IsVarArg;
- const SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
+ bool IsVarArg = CLI.getIsVarArg();
+ const auto &Outs = CLI.Outs;
const SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
- const SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;
+ const auto &Ins = CLI.Ins;
const SelectionDAG &DAG = CLI.DAG;
MachineFunction &MF = DAG.getMachineFunction();
const Function &CallerF = MF.getFunction();
@@ -10446,14 +10446,13 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
- SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
- bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID &CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
const CallBase *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
@@ -10519,9 +10518,9 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
std::optional<unsigned> ZAMarkerNode = getZAMarkerForCall(CallAttrs);
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
// Check if it's really possible to do a tail call.
- IsTailCall = isEligibleForTailCallOptimization(CLI);
+ CLI.setIsTailCall(isEligibleForTailCallOptimization(CLI));
// If we have a tail-call, it's safe to drop ZAMarkerNode since
// 1. INOUT_ZA_USE is the only marker node that can reach this point
@@ -10530,7 +10529,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// 2. INOUT_ZA_USE is redunant on a tail call, since a tail call is a return
// for which MachineSMEABIPass requires an acitve ZA state anyway, the
// marker node doesn't add anything.
- if (IsTailCall && ZAMarkerNode) {
+ if (CLI.getIsTailCall() && ZAMarkerNode) {
assert(ZAMarkerNode == AArch64ISD::INOUT_ZA_USE &&
"Unexpected SME ZA marker node");
ZAMarkerNode = std::nullopt;
@@ -10538,15 +10537,15 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// A sibling call is one where we're under the usual C ABI and not planning
// to change that but can still do a tail call:
- if (!ZAMarkerNode && !TailCallOpt && IsTailCall &&
+ if (!ZAMarkerNode && !TailCallOpt && CLI.getIsTailCall() &&
CallConv != CallingConv::Tail && CallConv != CallingConv::SwiftTail)
IsSibCall = true;
- if (IsTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
}
- if (!IsTailCall && CLI.CB && CLI.CB->isMustTailCall())
+ if (!CLI.getIsTailCall() && CLI.CB && CLI.CB->isMustTailCall())
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail");
@@ -10567,7 +10566,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
int FPDiff = 0;
const Align StackAlign = Subtarget->getFrameLowering()->getStackAlign();
- if (IsTailCall && !IsSibCall) {
+ if (CLI.getIsTailCall() && !IsSibCall) {
unsigned NumReusableBytes = FuncInfo->getBytesInStackArgArea();
// In general, neither NumBytes nor NumReusableBytes is guaranteed to be
@@ -10642,7 +10641,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
if (Outs.size() < 2)
report_fatal_error("variadic arm64ec_thunk_x64 call is missing the "
"x4/x5 (pointer/length) arguments");
- if (IsTailCall)
+ if (CLI.getIsTailCall())
report_fatal_error("tail calls are not supported for variadic "
"arm64ec_thunk_x64 calls");
@@ -10675,7 +10674,8 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// These operations are automatically eliminated by the prolog/epilog pass
assert((!IsSibCall || !ZAMarkerNode) && "ZA markers require CALLSEQ_START");
if (!IsSibCall) {
- Chain = DAG.getCALLSEQ_START(Chain, IsTailCall ? 0 : NumBytes, 0, DL);
+ Chain =
+ DAG.getCALLSEQ_START(Chain, CLI.getIsTailCall() ? 0 : NumBytes, 0, DL);
if (ZAMarkerNode) {
// Note: We need the CALLSEQ_START to glue the ZAMarkerNode to, simply
// using a chain can result in incorrect scheduling. The markers refer to
@@ -10899,7 +10899,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
unsigned LocMemOffset = VA.getLocMemOffset();
int32_t Offset = LocMemOffset + BEAlign;
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
// When the frame pointer is perfectly aligned for the tail call and the
// same stack argument is passed down intact, we can reuse it.
if (!FPDiff && !shouldLowerTailCallStackArg(MF, VA, Arg, Flags, Offset))
@@ -10950,7 +10950,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
if (IsVarArg && Subtarget->isWindowsArm64EC() &&
!(CLI.CB && CLI.CB->isMustTailCall()) && !IsArm64ECVarArgExitThunk) {
SDValue ParamPtr = StackPtr;
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
// Create a dummy object at the top of the stack that can be used to get
// the SP after the epilogue
int FI = MF.getFrameInfo().CreateFixedObject(1, FPDiff, true);
@@ -10999,7 +10999,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
if (OpFlags & AArch64II::MO_GOT) {
Callee = DAG.getTargetGlobalAddress(CalledGlobal, DL, PtrVT, 0, OpFlags);
Callee = DAG.getNode(AArch64ISD::LOADgot, DL, PtrVT, Callee);
- } else if (!CLI.PAI || !IsTailCall) {
+ } else if (!CLI.PAI || !CLI.getIsTailCall()) {
const GlobalValue *GV = G->getGlobal();
Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
}
@@ -11020,12 +11020,12 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// the frame up *after* the call, however in the ABI-changing tail-call case
// we've carefully laid out the parameters so that when sp is reset they'll be
// in the correct location.
- if (IsTailCall && !IsSibCall) {
+ if (CLI.getIsTailCall() && !IsSibCall) {
Chain = DAG.getCALLSEQ_END(Chain, 0, 0, InGlue, DL);
InGlue = Chain.getValue(1);
}
- unsigned Opc = IsTailCall ? AArch64ISD::TC_RETURN : AArch64ISD::CALL;
+ unsigned Opc = CLI.getIsTailCall() ? AArch64ISD::TC_RETURN : AArch64ISD::CALL;
std::vector<SDValue> Ops;
Ops.push_back(Chain);
@@ -11035,7 +11035,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// be expanded to the call, directly followed by a special marker sequence and
// a call to an ObjC library function. Use CALL_RVMARKER to do that.
if (CLI.CB && objcarc::hasAttachedCallOpBundle(CLI.CB)) {
- assert(!IsTailCall &&
+ assert(!CLI.getIsTailCall() &&
"tail calls cannot be marked with clang.arc.attachedcall");
Opc = AArch64ISD::CALL_RVMARKER;
@@ -11057,7 +11057,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
Opc = AArch64ISD::CALL_BTI;
}
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
// Each tail call may have to adjust the stack by a different amount, so
// this information must travel along with the operation for eventual
// consumption by emitEpilogue.
@@ -11077,7 +11077,8 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
if (Opc == AArch64ISD::CALL_RVMARKER)
Opc = AArch64ISD::AUTH_CALL_RVMARKER;
else
- Opc = IsTailCall ? AArch64ISD::AUTH_TC_RETURN : AArch64ISD::AUTH_CALL;
+ Opc = CLI.getIsTailCall() ? AArch64ISD::AUTH_TC_RETURN
+ : AArch64ISD::AUTH_CALL;
Ops.push_back(DAG.getTargetConstant(Key, DL, MVT::i32));
Ops.push_back(IntDisc);
Ops.push_back(AddrDisc);
@@ -11119,13 +11120,13 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
// If we're doing a tall call, use a TC_RETURN here rather than an
// actual call instruction.
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
MF.getFrameInfo().setHasTailCall();
SDValue Ret = DAG.getNode(Opc, DL, MVT::Other, Ops);
if (IsCFICall)
Ret->setCFIType(CLI.CFIType->getZExtValue());
- DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.getNoMerge());
DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
if (CalledGlobal &&
MF.getFunction().getParent()->getModuleFlag("import-call-optimization"))
@@ -11138,7 +11139,7 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
if (IsCFICall)
Chain->setCFIType(CLI.CFIType->getZExtValue());
- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.getNoMerge());
InGlue = Chain.getValue(1);
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
if (CalledGlobal &&
@@ -11199,10 +11200,11 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
return Result;
}
-bool AArch64TargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool AArch64TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
CCAssignFn *RetCC = CCAssignFnForReturn(CallConv);
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
@@ -11212,7 +11214,7 @@ bool AArch64TargetLowering::CanLowerReturn(
SDValue
AArch64TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
auto &MF = DAG.getMachineFunction();
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index a017e0508b57c..334a3a8c2dbf2 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -638,8 +638,7 @@ class AArch64TargetLowering : public TargetLowering {
SelectionDAG &DAG) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
@@ -691,12 +690,11 @@ class AArch64TargetLowering : public TargetLowering {
SDValue &Chain) const;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index f60a4deb98ab0..cbee946dd63ed 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/CFIInstBuilder.h"
#include "llvm/CodeGen/LivePhysRegs.h"
@@ -11957,10 +11958,11 @@ class AArch64PipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
/// The initial value of the loop counter
Register Init;
/// True iff Update is a predecessor of Comp
- bool IsUpdatePriorComp;
+ bool getIsUpdatePriorComp() const { return Cond.getFlag(0); }
+ void setIsUpdatePriorComp(bool Value) { Cond.setFlag(0, Value); }
/// The normalized condition used by createTripCountGreaterCondition()
- SmallVector<MachineOperand, 4> Cond;
+ llvm::SmallVectorWithFlags<MachineOperand, 4> Cond;
public:
AArch64PipelinerLoopInfo(MachineBasicBlock *LoopBB, MachineInstr *CondBranch,
@@ -11974,7 +11976,7 @@ class AArch64PipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
LoopBB(LoopBB), CondBranch(CondBranch), Comp(Comp),
CompCounterOprNum(CompCounterOprNum), Update(Update),
UpdateCounterOprNum(UpdateCounterOprNum), Init(Init),
- IsUpdatePriorComp(IsUpdatePriorComp), Cond(Cond.begin(), Cond.end()) {}
+ Cond(unsigned(IsUpdatePriorComp), Cond.begin(), Cond.end()) {}
bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
// Make the instructions for loop control be placed in stage 0.
@@ -11988,7 +11990,7 @@ class AArch64PipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
// A branch instruction will be inserted as "if (Cond) goto epilogue".
// Cond is normalized for such use.
// The predecessors of the branch are assumed to have already been inserted.
- CondParam = Cond;
+ CondParam.assign(Cond.begin(), Cond.end());
return {};
}
@@ -12080,7 +12082,7 @@ void AArch64PipelinerLoopInfo::createRemainingIterationsGreaterCondition(
if (I != TC) {
if (I == 0) {
- if (Update != Comp && IsUpdatePriorComp) {
+ if (Update != Comp && getIsUpdatePriorComp()) {
Counter =
LastStage0Insts[Comp]->getOperand(CompCounterOprNum).getReg();
NextCounter = cloneInstr(Update, UpdateCounterOprNum, Counter, MBB,
@@ -12102,7 +12104,7 @@ void AArch64PipelinerLoopInfo::createRemainingIterationsGreaterCondition(
// use initial counter value (testing if the trip count is sufficient to
// be executed by pipelined code)
Counter = Init;
- if (IsUpdatePriorComp)
+ if (getIsUpdatePriorComp())
Counter =
cloneInstr(Update, UpdateCounterOprNum, Counter, MBB, MBB.end());
} else {
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
index 004315b025119..fa11aaa777d6c 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -122,8 +122,8 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
if (F.hasFnAttribute(Attribute::NoRedZone))
HasRedZone = false;
SignCondition = GetSignReturnAddress(F);
- SignWithBKey = ShouldSignWithBKey(F, *STI);
- HasELFSignedGOT = hasELFSignedGOTHelper(F, STI);
+ setSignWithBKey(ShouldSignWithBKey(F, *STI));
+ setHasELFSignedGOT(hasELFSignedGOTHelper(F, STI));
// TODO: skip functions that have no instrumented allocas for optimization
IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
@@ -140,8 +140,8 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
}
// BTI/PAuthLR are set on the function attribute.
- BranchTargetEnforcement = F.hasFnAttribute("branch-target-enforcement");
- BranchProtectionPAuthLR = F.hasFnAttribute("branch-protection-pauth-lr");
+ setBranchTargetEnforcement(F.hasFnAttribute("branch-target-enforcement"));
+ setBranchProtectionPAuthLR(F.hasFnAttribute("branch-protection-pauth-lr"));
// Parse the SME function attributes.
SMEFnAttrs = SMEAttrs(F);
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
index 5860dff473823..6db0b19197bf8 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -82,8 +83,18 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
unsigned CalleeSavedStackSize = 0;
unsigned ZPRCalleeSavedStackSize = 0;
unsigned PPRCalleeSavedStackSize = 0;
- bool HasCalleeSavedStackSize = false;
- bool HasSVECalleeSavedStackSize = false;
+ bool getHasCalleeSavedStackSize() const {
+ return JumpTableEntryInfo.getFlag(0);
+ }
+ void setHasCalleeSavedStackSize(bool Value) {
+ JumpTableEntryInfo.setFlag(0, Value);
+ }
+ bool getHasSVECalleeSavedStackSize() const {
+ return JumpTableEntryInfo.getFlag(1);
+ }
+ void setHasSVECalleeSavedStackSize(bool Value) {
+ JumpTableEntryInfo.setFlag(1, Value);
+ }
/// Number of TLS accesses using the special (combinable)
/// _TLS_MODULE_BASE_ symbol.
@@ -178,12 +189,14 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
SignReturnAddress SignCondition = SignReturnAddress::None;
/// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
- bool SignWithBKey = false;
+ bool getSignWithBKey() const { return JumpTableEntryInfo.getFlag(2); }
+ void setSignWithBKey(bool Value) { JumpTableEntryInfo.setFlag(2, Value); }
/// HasELFSignedGOT is true if the target binary format is ELF and the IR
/// module containing the corresponding function has "ptrauth-elf-got" flag
/// set to 1.
- bool HasELFSignedGOT = false;
+ bool getHasELFSignedGOT() const { return JumpTableEntryInfo.getFlag(3); }
+ void setHasELFSignedGOT(bool Value) { JumpTableEntryInfo.setFlag(3, Value); }
/// SigningInstrOffset captures the offset of the PAC-RET signing instruction
/// within the prologue, so it can be re-used for authentication in the
@@ -198,18 +211,29 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
/// BranchTargetEnforcement enables placing BTI instructions at potential
/// indirect branch destinations.
- bool BranchTargetEnforcement = false;
+ bool getBranchTargetEnforcement() const { return LOHContainerSet.getFlag(0); }
+ void setBranchTargetEnforcement(bool Value) {
+ LOHContainerSet.setFlag(0, Value);
+ }
/// Indicates that SP signing should be diversified with PC as-per PAuthLR.
/// This is set by -mbranch-protection and will emit NOP instructions unless
/// the subtarget feature +pauthlr is also used (in which case non-NOP
/// instructions are emitted).
- bool BranchProtectionPAuthLR = false;
+ bool getBranchProtectionPAuthLR() const { return LOHContainerSet.getFlag(1); }
+ void setBranchProtectionPAuthLR(bool Value) {
+ LOHContainerSet.setFlag(1, Value);
+ }
/// Whether this function has an extended frame record [Ctx, FP, LR]. If so,
/// bit 60 of the in-memory FP will be 1 to enable other tools to detect the
/// extended record.
- bool HasSwiftAsyncContext = false;
+ bool getHasSwiftAsyncContextFlag() const {
+ return LOHContainerSet.getFlag(2);
+ }
+ void setHasSwiftAsyncContextFlag(bool Value) {
+ LOHContainerSet.setFlag(2, Value);
+ }
/// The stack slot where the Swift asynchronous context is stored.
int SwiftAsyncContextFrameIdx = std::numeric_limits<int>::max();
@@ -337,7 +361,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
void setCalleeSavedStackSize(unsigned Size) {
CalleeSavedStackSize = Size;
- HasCalleeSavedStackSize = true;
+ setHasCalleeSavedStackSize(true);
}
// When CalleeSavedStackSize has not been set (for example when
@@ -352,10 +376,10 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
// Make sure the calculated size derived from the CalleeSavedInfo
// equals the cached size that was calculated elsewhere (e.g. in
// determineCalleeSaves).
- ValidateCalleeSavedStackSize = HasCalleeSavedStackSize;
+ ValidateCalleeSavedStackSize = getHasCalleeSavedStackSize();
#endif
- if (!HasCalleeSavedStackSize || ValidateCalleeSavedStackSize) {
+ if (!getHasCalleeSavedStackSize() || ValidateCalleeSavedStackSize) {
assert(MFI.isCalleeSavedInfoValid() && "CalleeSavedInfo not calculated");
if (MFI.getCalleeSavedInfo().empty())
return 0;
@@ -387,7 +411,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
}
unsigned Size = alignTo(MaxOffset - MinOffset, 16);
- assert((!HasCalleeSavedStackSize || getCalleeSavedStackSize() == Size) &&
+ assert((!getHasCalleeSavedStackSize() ||
+ getCalleeSavedStackSize() == Size) &&
"Invalid size calculated for callee saves");
return Size;
}
@@ -396,7 +421,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
}
unsigned getCalleeSavedStackSize() const {
- assert(HasCalleeSavedStackSize &&
+ assert(getHasCalleeSavedStackSize() &&
"CalleeSavedStackSize has not been calculated");
return CalleeSavedStackSize;
}
@@ -407,15 +432,15 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
"expected SVE callee-save sizes to be aligned to 16-bytes");
ZPRCalleeSavedStackSize = ZPR;
PPRCalleeSavedStackSize = PPR;
- HasSVECalleeSavedStackSize = true;
+ setHasSVECalleeSavedStackSize(true);
}
unsigned getZPRCalleeSavedStackSize() const {
- assert(HasSVECalleeSavedStackSize &&
+ assert(getHasSVECalleeSavedStackSize() &&
"ZPRCalleeSavedStackSize has not been calculated");
return ZPRCalleeSavedStackSize;
}
unsigned getPPRCalleeSavedStackSize() const {
- assert(HasSVECalleeSavedStackSize &&
+ assert(getHasSVECalleeSavedStackSize() &&
"PPRCalleeSavedStackSize has not been calculated");
return PPRCalleeSavedStackSize;
}
@@ -522,7 +547,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
using MILOHArgs = MILOHDirective::LOHArgs;
using MILOHContainer = SmallVector<MILOHDirective, 32>;
- const MILOHContainer &getLOHContainer() const { return LOHContainerSet; }
+ ArrayRef<MILOHDirective> getLOHContainer() const { return LOHContainerSet; }
/// Add a LOH directive of this @p Kind and this @p Args.
void addLOHDirective(MCLOHType Kind, MILOHArgs Args) {
@@ -578,9 +603,9 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
bool needsShadowCallStackPrologueEpilogue(MachineFunction &MF) const;
- bool shouldSignWithBKey() const { return SignWithBKey; }
+ bool shouldSignWithBKey() const { return getSignWithBKey(); }
- bool hasELFSignedGOT() const { return HasELFSignedGOT; }
+ bool hasELFSignedGOT() const { return getHasELFSignedGOT(); }
MCSymbol *getSigningInstrLabel() const { return SignInstrLabel; }
void setSigningInstrLabel(MCSymbol *Label) { SignInstrLabel = Label; }
@@ -591,14 +616,14 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
return SignReturnAddressHardening != SignReturnAddressHardeningKind::None;
}
- bool branchTargetEnforcement() const { return BranchTargetEnforcement; }
+ bool branchTargetEnforcement() const { return getBranchTargetEnforcement(); }
- bool branchProtectionPAuthLR() const { return BranchProtectionPAuthLR; }
+ bool branchProtectionPAuthLR() const { return getBranchProtectionPAuthLR(); }
void setHasSwiftAsyncContext(bool HasContext) {
- HasSwiftAsyncContext = HasContext;
+ setHasSwiftAsyncContextFlag(HasContext);
}
- bool hasSwiftAsyncContext() const { return HasSwiftAsyncContext; }
+ bool hasSwiftAsyncContext() const { return getHasSwiftAsyncContextFlag(); }
void setSwiftAsyncContextFrameIdx(int FI) {
SwiftAsyncContextFrameIdx = FI;
@@ -619,10 +644,11 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
private:
// Hold the lists of LOHs.
- MILOHContainer LOHContainerSet;
+ llvm::SmallVectorWithFlagsFor<MILOHContainer, 3> LOHContainerSet;
SetOfInstructions LOHRelated;
- SmallVector<std::pair<unsigned, MCSymbol *>, 2> JumpTableEntryInfo;
+ llvm::SmallVectorWithFlags<std::pair<unsigned, MCSymbol *>, 2, 4>
+ JumpTableEntryInfo;
};
namespace yaml {
diff --git a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
index dbeb55d65e8d4..27cf07e7833a8 100644
--- a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
+++ b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
@@ -567,8 +567,8 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
// postdominator analysis, and will leave us to keep memory tagged after
// function return. Work around this by always untagging at every return
// statement if return_twice functions are called.
- bool StandardLifetime =
- !SInfo.CallsReturnTwice && memtag::isSupportedLifetime(Info, DT, LI);
+ bool StandardLifetime = !SInfo.getCallsReturnTwice() &&
+ memtag::isSupportedLifetime(Info, DT, LI);
if (StandardLifetime) {
uint64_t Size = *Info.AI->getAllocationSize(*DL);
Size = alignTo(Size, kTagGranuleSize);
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 14e8d3b61c2dc..3fa716da8e92c 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -6606,8 +6606,8 @@ bool AArch64TTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
case Intrinsic::aarch64_neon_ld2:
case Intrinsic::aarch64_neon_ld3:
case Intrinsic::aarch64_neon_ld4:
- Info.ReadMem = true;
- Info.WriteMem = false;
+ Info.setReadMem(true);
+ Info.setWriteMem(false);
Info.PtrVal = Inst->getArgOperand(0);
break;
case Intrinsic::aarch64_neon_st1x2:
@@ -6616,8 +6616,8 @@ bool AArch64TTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
case Intrinsic::aarch64_neon_st2:
case Intrinsic::aarch64_neon_st3:
case Intrinsic::aarch64_neon_st4:
- Info.ReadMem = false;
- Info.WriteMem = true;
+ Info.setReadMem(false);
+ Info.setWriteMem(true);
Info.PtrVal = Inst->getArgOperand(Inst->arg_size() - 1);
break;
}
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
index 18a41f98a7634..04c16649820be 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp
@@ -1222,7 +1222,7 @@ bool AArch64CallLowering::lowerTailCall(
unsigned Opc = getCallOpcode(MF, Info.Callee.isReg(), true, Info.PAI, MRI);
auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
MIB.add(Info.Callee);
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::MIFlag::NoMerge);
// Tell the call which registers are clobbered.
@@ -1475,7 +1475,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
}
auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::MIFlag::NoMerge);
unsigned CalleeOpNo = 0;
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index d8384e13f345b..ff9d6f7c22046 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1861,7 +1861,7 @@ void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, uint64_t Address,
const MCSubtargetInfo &STI,
raw_ostream &O) {
// Do not print the numeric target address when symbolizing.
- if (SymbolizeOperands)
+ if (getSymbolizeOperands())
return;
const MCOperand &Op = MI->getOperand(OpNum);
@@ -1870,7 +1870,7 @@ void AArch64InstPrinter::printAlignedLabel(const MCInst *MI, uint64_t Address,
// we're running the disassembler), just print the immediate.
if (Op.isImm()) {
int64_t Offset = Op.getImm() * 4;
- if (PrintBranchImmAsAddress)
+ if (getPrintBranchImmAsAddress())
markup(O, Markup::Target) << formatHex(Address + Offset);
else
markup(O, Markup::Immediate) << "#" << formatImm(Offset);
@@ -1896,7 +1896,7 @@ void AArch64InstPrinter::printAdrAdrpLabel(const MCInst *MI, uint64_t Address,
// Do not print the numeric target address when symbolizing.
// However, do print for ADRP, as this is typically used together with an ADD
// or an immediate-offset ldr/str and the label is likely at the wrong point.
- if (SymbolizeOperands && MI->getOpcode() != AArch64::ADRP)
+ if (getSymbolizeOperands() && MI->getOpcode() != AArch64::ADRP)
return;
const MCOperand &Op = MI->getOperand(OpNum);
@@ -1910,7 +1910,7 @@ void AArch64InstPrinter::printAdrAdrpLabel(const MCInst *MI, uint64_t Address,
Address = Address & -4096;
}
WithMarkup M = markup(O, Markup::Immediate);
- if (PrintBranchImmAsAddress)
+ if (getPrintBranchImmAsAddress())
markup(O, Markup::Target) << formatHex(Address + Offset);
else
markup(O, Markup::Immediate) << "#" << Offset;
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
index ff3b3f12e2dc6..1321e9a97d19d 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
@@ -171,7 +171,7 @@ void AArch64TargetStreamer::emitAttributesSubsection(
std::unique_ptr<MCELFStreamer::AttributeSubSection>
AArch64TargetStreamer::getActiveAttributesSubsection() {
for (MCELFStreamer::AttributeSubSection &SubSection : AttributeSubSections) {
- if (SubSection.IsActive) {
+ if (SubSection.getIsActive()) {
return std::make_unique<MCELFStreamer::AttributeSubSection>(SubSection);
}
}
@@ -203,7 +203,7 @@ void AArch64TargetStreamer::emitAttribute(StringRef VendorName, unsigned Tag,
for (MCELFStreamer::AttributeSubSection &SubSection : AttributeSubSections) {
if (VendorName == SubSection.VendorName) {
- if (!SubSection.IsActive) {
+ if (!SubSection.getIsActive()) {
assert(0 &&
"Can not add AArch64 build attribute: subsection is not active");
return;
@@ -236,9 +236,9 @@ void AArch64TargetStreamer::emitAttribute(StringRef VendorName, unsigned Tag,
void AArch64TargetStreamer::activateAttributesSubsection(StringRef VendorName) {
for (MCELFStreamer::AttributeSubSection &SubSection : AttributeSubSections) {
if (VendorName == SubSection.VendorName) {
- SubSection.IsActive = true;
+ SubSection.setIsActive(true);
} else {
- SubSection.IsActive = false;
+ SubSection.setIsActive(false);
}
}
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
index 6aa5c0de451ba..be307789abf06 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp
@@ -145,11 +145,11 @@ AMDGPUTargetStreamer *AMDGPUAsmPrinter::getTargetStreamer() const {
}
void AMDGPUAsmPrinter::emitStartOfAsmFile(Module &M) {
- IsTargetStreamerInitialized = false;
+ setIsTargetStreamerInitialized(false);
}
void AMDGPUAsmPrinter::initTargetStreamer(Module &M) {
- IsTargetStreamerInitialized = true;
+ setIsTargetStreamerInitialized(true);
// TODO: Which one is called first, emitStartOfAsmFile or
// emitFunctionBodyStart?
@@ -174,7 +174,7 @@ void AMDGPUAsmPrinter::initTargetStreamer(Module &M) {
void AMDGPUAsmPrinter::emitEndOfAsmFile(Module &M) {
// Init target streamer if it has not yet happened
- if (!IsTargetStreamerInitialized)
+ if (!getIsTargetStreamerInitialized())
initTargetStreamer(M);
const Triple &TT = M.getTargetTriple();
@@ -683,7 +683,7 @@ void AMDGPUAsmPrinter::emitAMDGPUInfo(Module &M) {
return;
AMDGPU::InfoSectionData Data;
- Data.Funcs = std::move(FunctionInfos);
+ Data.Funcs = SmallVector<AMDGPU::FuncInfo, 8>(std::move(FunctionInfos));
for (auto &[F, TypeId] : AddrTakenTypeIds) {
MCSymbol *Sym = getSymbol(F);
@@ -897,7 +897,7 @@ AMDGPUAsmPrinter::getAmdhsaKernelDescriptor(const MachineFunction &MF,
bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// Init target streamer lazily on the first function so that previous passes
// can set metadata.
- if (!IsTargetStreamerInitialized)
+ if (!getIsTargetStreamerInitialized())
initTargetStreamer(*MF.getFunction().getParent());
ResourceUsage = GetResourceUsage(MF);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h
index 4394cde308665..8031acf49eb8f 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.h
@@ -19,6 +19,7 @@
#include "MCTargetDesc/AMDGPUTargetStreamer.h"
#include "SIProgramInfo.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/AsmPrinter.h"
namespace llvm {
@@ -94,7 +95,7 @@ class AMDGPUAsmPrinter final : public AsmPrinter {
SetVector<std::pair<MCSymbol *, MCSymbol *>> DirectCallEdges;
- SmallVector<AMDGPU::FuncInfo, 8> FunctionInfos;
+ llvm::SmallVectorWithFlags<AMDGPU::FuncInfo, 8> FunctionInfos;
SmallString<128> getMCExprStr(const MCExpr *Value);
@@ -161,7 +162,12 @@ class AMDGPUAsmPrinter final : public AsmPrinter {
std::vector<std::string> DisasmLines, HexLines;
size_t DisasmLineMaxLen;
- bool IsTargetStreamerInitialized;
+ bool getIsTargetStreamerInitialized() const {
+ return FunctionInfos.getFlag(0);
+ }
+ void setIsTargetStreamerInitialized(bool Value) {
+ FunctionInfos.setFlag(0, Value);
+ }
};
class AMDGPUAsmPrinterBeginPass
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
index b482f69d81529..462b1f2f09b40 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp
@@ -1353,7 +1353,7 @@ bool AMDGPUCallLowering::lowerTailCall(
unsigned Opc = getCallOpcode(MF, Info.Callee.isReg(), /*IsTailCall*/ true,
ST.isWave32(), CalleeCC, IsDynamicVGPRChainCall);
auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::NoMerge);
if (FuncInfo->isWholeWaveFunction())
@@ -1664,9 +1664,9 @@ bool AMDGPUCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
auto MIB = MIRBuilder.buildInstrNoInsert(Opc);
MIB.addDef(TRI->getReturnAddressReg(MF), RegState::Dead);
- if (!Info.IsConvergent)
+ if (!Info.getIsConvergent())
MIB.setMIFlag(MachineInstr::NoConvergent);
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::NoMerge);
if (!addCallTargetOperands(MIB, MIRBuilder, Info))
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
index 8ea07519116b9..84578bd00fb58 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
@@ -18,6 +18,7 @@
#include "AMDGPUIGroupLP.h"
#include "SIInstrInfo.h"
#include "SIMachineFunctionInfo.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/TargetOpcodes.h"
@@ -230,7 +231,7 @@ class PipelineSolver {
// Instructions that can be assigned to multiple SchedGroups
DenseMap<int, SUnitsToCandidateSGsMap> SyncedInstrs;
- SmallVector<SUsToCandSGsVec, 4> PipelineInstrs;
+ llvm::SmallVectorWithFlags<SUsToCandSGsVec, 4, 2> PipelineInstrs;
DenseMap<int, SmallVector<SchedGroup, 4>> SyncedSchedGroups;
// The current working pipeline
SmallVector<SmallVector<SchedGroup, 4>, 4> CurrPipeline;
@@ -238,7 +239,8 @@ class PipelineSolver {
SmallVector<SmallVector<SchedGroup, 4>, 4> BestPipeline;
// Whether or not we actually have any SyncedInstrs to try to solve.
- bool NeedsSolver = false;
+ bool getNeedsSolver() const { return PipelineInstrs.getFlag(0); }
+ void setNeedsSolver(bool Value) { PipelineInstrs.setFlag(0, Value); }
// Compute an estimate of the size of search tree -- the true size is
// the product of each conflictedInst.Matches.size() across all SyncPipelines
@@ -263,7 +265,8 @@ class PipelineSolver {
uint64_t BranchesExplored = 0;
// The direction in which we process the candidate SchedGroups per SU
- bool IsBottomUp = true;
+ bool getIsBottomUp() const { return !PipelineInstrs.getFlag(1); }
+ void setIsBottomUp(bool Value) { PipelineInstrs.setFlag(1, !Value); }
// Update indices to fit next conflicting instruction
void advancePosition();
@@ -361,16 +364,18 @@ class PipelineSolver {
DenseMap<int, SUnitsToCandidateSGsMap> &SyncedInstrs,
ScheduleDAGMI *DAG, bool IsBottomUp = true)
: DAG(DAG), SyncedInstrs(SyncedInstrs),
- SyncedSchedGroups(SyncedSchedGroups), IsBottomUp(IsBottomUp) {
+ PipelineInstrs(decltype(this->PipelineInstrs)::withFlags(
+ (unsigned(!(IsBottomUp)) << 1))),
+ SyncedSchedGroups(SyncedSchedGroups) {
for (auto &PipelineInstrs : SyncedInstrs) {
if (!PipelineInstrs.second.empty()) {
- NeedsSolver = true;
+ setNeedsSolver(true);
break;
}
}
- if (!NeedsSolver)
+ if (!getNeedsSolver())
return;
convertSyncMapsToArrays();
@@ -463,8 +468,9 @@ void PipelineSolver::makePipeline() {
}
for (auto &SyncPipeline : BestPipeline) {
- IsBottomUp ? linkSchedGroups(SyncPipeline.rbegin(), SyncPipeline.rend())
- : linkSchedGroups(SyncPipeline.begin(), SyncPipeline.end());
+ getIsBottomUp()
+ ? linkSchedGroups(SyncPipeline.rbegin(), SyncPipeline.rend())
+ : linkSchedGroups(SyncPipeline.begin(), SyncPipeline.end());
}
}
@@ -599,10 +605,10 @@ int PipelineSolver::addEdges(
// opposite is true if !IsBottomUp. IsBottomUp occurs in the case of multiple
// SCHED_GROUP_BARRIERS, or if a user specifies IGLP_OPT SchedGroups using
// IsBottomUp (in reverse).
- return IsBottomUp ? linkSUnit(SU, SGID, AddedEdges, SyncPipeline.rbegin(),
- SyncPipeline.rend())
- : linkSUnit(SU, SGID, AddedEdges, SyncPipeline.begin(),
- SyncPipeline.end());
+ return getIsBottomUp() ? linkSUnit(SU, SGID, AddedEdges,
+ SyncPipeline.rbegin(), SyncPipeline.rend())
+ : linkSUnit(SU, SGID, AddedEdges, SyncPipeline.begin(),
+ SyncPipeline.end());
}
void PipelineSolver::removeEdges(
@@ -727,10 +733,10 @@ bool PipelineSolver::solveExact() {
// SchedGroup -> Cost pairs
SmallVector<std::pair<int, int>, 4> ReadyList;
// Prioritize the candidate sched groups in terms of lowest cost first
- IsBottomUp ? populateReadyList(ReadyList, CurrSU.second.rbegin(),
- CurrSU.second.rend())
- : populateReadyList(ReadyList, CurrSU.second.begin(),
- CurrSU.second.end());
+ getIsBottomUp() ? populateReadyList(ReadyList, CurrSU.second.rbegin(),
+ CurrSU.second.rend())
+ : populateReadyList(ReadyList, CurrSU.second.begin(),
+ CurrSU.second.end());
auto *I = ReadyList.begin();
auto *E = ReadyList.end();
@@ -823,7 +829,7 @@ void PipelineSolver::greedyFind(
LLVM_DEBUG(dbgs() << "Fitting " << *CurrSU.first << " in Pipeline # "
<< CurrSyncGroupIdx << "\n");
- EdgeSetBuilder Builder(CurrSU.first, SyncPipeline, IsBottomUp);
+ EdgeSetBuilder Builder(CurrSU.first, SyncPipeline, getIsBottomUp());
// Since we have added the potential SchedGroups from bottom up, but
// traversed the DAG from top down, parse over the groups from last to
@@ -887,7 +893,7 @@ bool PipelineSolver::solveGreedy() {
while (static_cast<size_t>(CurrSyncGroupIdx) < PipelineInstrs.size()) {
SUToCandSGsPair CurrSU = PipelineInstrs[CurrSyncGroupIdx][CurrConflInstNo];
- IsBottomUp
+ getIsBottomUp()
? greedyFind(AddedEdges, CurrSU.second.rbegin(), CurrSU.second.rend())
: greedyFind(AddedEdges, CurrSU.second.begin(), CurrSU.second.end());
advancePosition();
@@ -907,7 +913,7 @@ unsigned PipelineSolver::computeProblemSize() {
}
void PipelineSolver::solve() {
- if (!NeedsSolver)
+ if (!getNeedsSolver())
return;
unsigned ProblemSize = computeProblemSize();
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index c9ef618e1e7b3..984ea366274ea 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -1186,8 +1186,7 @@ CCAssignFn *AMDGPUCallLowering::CCAssignFnForReturn(CallingConv::ID CC,
/// calling convention analysis function and the register type (Ins[x].VT) as
/// the ValVT.
void AMDGPUTargetLowering::analyzeFormalArgumentsCompute(
- CCState &State,
- const SmallVectorImpl<ISD::InputArg> &Ins) const {
+ CCState &State, llvm::ArrayRef<ISD::InputArg> Ins) const {
const MachineFunction &MF = State.getMachineFunction();
const Function &Fn = MF.getFunction();
LLVMContext &Ctx = Fn.getContext();
@@ -1299,12 +1298,12 @@ void AMDGPUTargetLowering::analyzeFormalArgumentsCompute(
}
}
-SDValue AMDGPUTargetLowering::LowerReturn(
- SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &DL, SelectionDAG &DAG) const {
+SDValue
+AMDGPUTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL, SelectionDAG &DAG) const {
// FIXME: Fails for r600 tests
//assert(!isVarArg && Outs.empty() && OutVals.empty() &&
// "wave terminate should not have return values");
@@ -1378,7 +1377,7 @@ SDValue AMDGPUTargetLowering::lowerUnhandledCall(CallLoweringInfo &CLI,
DAG.getContext()->diagnose(
DiagnosticInfoUnsupported(Fn, Reason + FuncName, CLI.DL.getDebugLoc()));
- if (!CLI.IsTailCall) {
+ if (!CLI.getIsTailCall()) {
for (ISD::InputArg &Arg : CLI.Ins)
InVals.push_back(DAG.getPOISON(Arg.VT));
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
index 0cec051030d0b..b594a843df7b5 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h
@@ -182,9 +182,8 @@ class AMDGPUTargetLowering : public TargetLowering {
void LowerUDIVREM64(SDValue Op, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &Results) const;
- void analyzeFormalArgumentsCompute(
- CCState &State,
- const SmallVectorImpl<ISD::InputArg> &Ins) const;
+ void analyzeFormalArgumentsCompute(CCState &State,
+ llvm::ArrayRef<ISD::InputArg> Ins) const;
public:
AMDGPUTargetLowering(const TargetMachine &TM, const TargetSubtargetInfo &STI,
@@ -260,7 +259,7 @@ class AMDGPUTargetLowering : public TargetLowering {
static CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg);
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp
index 23653d4229530..e911ab174f5f5 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp
@@ -12,6 +12,7 @@
#include "AMDGPULibFunc.h"
#include "AMDGPU.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
@@ -786,8 +787,10 @@ namespace {
// substitution.
class ItaniumMangler {
- SmallVector<AMDGPULibFunc::Param, 10> Str; // list of accumulated substitutions
- bool UseAddrSpace;
+ llvm::SmallVectorWithFlags<AMDGPULibFunc::Param, 10>
+ Str; // list of accumulated substitutions
+ bool getUseAddrSpace() const { return Str.getFlag(0); }
+ void setUseAddrSpace(bool Value) { Str.setFlag(0, Value); }
int findSubst(const AMDGPULibFunc::Param& P) const {
for(unsigned I = 0; I < Str.size(); ++I) {
@@ -815,7 +818,7 @@ class ItaniumMangler {
public:
ItaniumMangler(bool useAddrSpace)
- : UseAddrSpace(useAddrSpace) {}
+ : Str(decltype(Str)::withFlags(unsigned(useAddrSpace))) {}
template <typename Stream>
void operator()(Stream& os, AMDGPULibFunc::Param p) {
@@ -837,7 +840,7 @@ class ItaniumMangler {
os << 'P';
if (p.PtrKind & AMDGPULibFunc::CONST) os << 'K';
if (p.PtrKind & AMDGPULibFunc::VOLATILE) os << 'V';
- unsigned AS = UseAddrSpace
+ unsigned AS = getUseAddrSpace()
? AMDGPULibFuncBase::getAddrSpaceFromEPtrKind(p.PtrKind)
: 0;
if (EnableOCLManglingMismatchWA || AS != 0)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
index 3e190190ee761..7452679995b7a 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
@@ -514,9 +514,9 @@ bool GCNTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
Info.PtrVal = Inst->getArgOperand(0);
Info.Ordering = static_cast<AtomicOrdering>(OrderingVal);
- Info.ReadMem = true;
- Info.WriteMem = true;
- Info.IsVolatile = !Volatile->isZero();
+ Info.setReadMem(true);
+ Info.setWriteMem(true);
+ Info.setIsVolatile(!Volatile->isZero());
return true;
}
default:
diff --git a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
index 057c72d962dc1..9361b4edfebc6 100644
--- a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp
@@ -1015,7 +1015,7 @@ GCNScheduleDAGMILive::GCNScheduleDAGMILive(
// We want regions with a single MI to be scheduled so that we can reason
// about them correctly during scheduling stages that move MIs between regions
// (e.g., rematerialization).
- ScheduleSingleMIRegions = true;
+ setScheduleSingleMIRegions(true);
LLVM_DEBUG(dbgs() << "Starting occupancy is " << StartingOccupancy << ".\n");
if (RelaxedOcc) {
MinOccupancy = std::min(MFI.getMinAllowedOccupancy(), StartingOccupancy);
@@ -1924,7 +1924,7 @@ bool ClusteredLowOccStage::initGCNRegion() {
}
bool PreRARematStage::initGCNRegion() {
- return !RevertAllRegions && RescheduleRegions[RegionIdx] &&
+ return !getRevertAllRegions() && RescheduleRegions[RegionIdx] &&
GCNSchedStage::initGCNRegion();
}
@@ -1969,7 +1969,7 @@ void PreRARematStage::finalizeGCNRegion() {
REMAT_DEBUG(dbgs() << "Region " << RegionIdx
<< " cannot meet occupancy target, interrupting "
"re-scheduling in all regions\n");
- RevertAllRegions = true;
+ setRevertAllRegions(true);
}
}
diff --git a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h
index 021a1e82f1303..a03df909462ed 100644
--- a/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h
+++ b/llvm/lib/Target/AMDGPU/GCNSchedStrategy.h
@@ -15,6 +15,7 @@
#include "GCNRegPressure.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -732,9 +733,10 @@ class PreRARematStage : public GCNSchedStage {
};
/// After re-scheduling, contains pre-re-scheduling data for all re-scheduled
/// regions.
- SmallVector<RegionSchedRevert> RegionReverts;
+ llvm::SmallVectorWithFlags<RegionSchedRevert> RegionReverts;
/// Whether we should revert all re-scheduled regions.
- bool RevertAllRegions = false;
+ bool getRevertAllRegions() const { return RegionReverts.getFlag(0); }
+ void setRevertAllRegions(bool Value) { RegionReverts.setFlag(0, Value); }
/// Returns the occupancy the stage is trying to achieve.
unsigned getStageTargetOccupancy() const;
diff --git a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
index 5a9c18c3ae5db..ed37b6732f6da 100644
--- a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -1424,8 +1424,8 @@ CCAssignFn *R600TargetLowering::CCAssignFnForCall(CallingConv::ID CC,
/// separate calling conventions for kernel and non-kernel functions.
SDValue R600TargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
*DAG.getContext());
diff --git a/llvm/lib/Target/AMDGPU/R600ISelLowering.h b/llvm/lib/Target/AMDGPU/R600ISelLowering.h
index e1b0afb8f3186..39e607c24bd2a 100644
--- a/llvm/lib/Target/AMDGPU/R600ISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/R600ISelLowering.h
@@ -37,8 +37,7 @@ class R600TargetLowering final : public AMDGPUTargetLowering {
SelectionDAG &DAG) const override;
CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &,
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 66f6a9dfeed99..f40c7994a975e 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -3196,7 +3196,7 @@ void SITargetLowering::allocateHSAUserSGPRs(CCState &CCInfo,
// sequential starting from the first argument.
void SITargetLowering::allocatePreloadKernArgSGPRs(
CCState &CCInfo, SmallVectorImpl<CCValAssign> &ArgLocs,
- const SmallVectorImpl<ISD::InputArg> &Ins, MachineFunction &MF,
+ llvm::ArrayRef<ISD::InputArg> Ins, MachineFunction &MF,
const SIRegisterInfo &TRI, SIMachineFunctionInfo &Info) const {
Function &F = MF.getFunction();
unsigned LastExplicitArgOffset = Subtarget->getExplicitKernelArgOffset();
@@ -3498,8 +3498,8 @@ void SITargetLowering::insertCopiesSplitCSR(
SDValue SITargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
const SIRegisterInfo *TRI = getSubtarget()->getRegisterInfo();
MachineFunction &MF = DAG.getMachineFunction();
@@ -3838,10 +3838,11 @@ SDValue SITargetLowering::LowerFormalArguments(
// TODO: If return values can't fit in registers, we should return as many as
// possible in registers before passing on stack.
-bool SITargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool SITargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
// Replacing returns with sret/stack usage doesn't make sense for shaders.
// FIXME: Also sort of a workaround for custom vector splitting in LowerReturn
// for shaders. Vector types should be explicitly handled by CC.
@@ -3863,12 +3864,12 @@ bool SITargetLowering::CanLowerReturn(
return true;
}
-SDValue
-SITargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &DL, SelectionDAG &DAG) const {
+SDValue SITargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL,
+ SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
const SIRegisterInfo *TRI = getSubtarget()->getRegisterInfo();
@@ -3966,8 +3967,8 @@ SITargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
SDValue SITargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool IsThisReturn,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals, bool IsThisReturn,
SDValue ThisVal) const {
CCAssignFn *RetCC = CCAssignFnForReturn(CallConv, IsVarArg);
@@ -4205,9 +4206,9 @@ void SITargetLowering::passSpecialInputs(
bool SITargetLowering::isEligibleForTailCallOptimization(
SDValue Callee, CallingConv::ID CalleeCC, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const {
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ SelectionDAG &DAG) const {
if (AMDGPU::isChainCC(CalleeCC))
return true;
@@ -4396,16 +4397,15 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
}
}
- SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
- SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;
- bool &IsTailCall = CLI.IsTailCall;
- bool IsVarArg = CLI.IsVarArg;
+ auto &Ins = CLI.Ins;
+ bool IsVarArg = CLI.getIsVarArg();
bool IsSibCall = false;
MachineFunction &MF = DAG.getMachineFunction();
if (Callee.isUndef() || isNullConstant(Callee)) {
- if (!CLI.IsTailCall) {
+ if (!CLI.getIsTailCall()) {
for (ISD::InputArg &Arg : CLI.Ins)
InVals.push_back(DAG.getPOISON(Arg.VT));
}
@@ -4421,15 +4421,15 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
if (!CLI.CB)
return lowerUnhandledCall(CLI, InVals, "unsupported libcall legalization");
- if (IsTailCall && MF.getTarget().Options.GuaranteedTailCallOpt) {
+ if (CLI.getIsTailCall() && MF.getTarget().Options.GuaranteedTailCallOpt) {
return lowerUnhandledCall(CLI, InVals,
"unsupported required tail call to function ");
}
- if (IsTailCall) {
- IsTailCall = isEligibleForTailCallOptimization(Callee, CallConv, IsVarArg,
- Outs, OutVals, Ins, DAG);
- if (!IsTailCall &&
+ if (CLI.getIsTailCall()) {
+ CLI.setIsTailCall(isEligibleForTailCallOptimization(
+ Callee, CallConv, IsVarArg, Outs, OutVals, Ins, DAG));
+ if (!CLI.getIsTailCall() &&
((CLI.CB && CLI.CB->isMustTailCall()) || IsChainCallConv)) {
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail or on llvm.amdgcn.cs.chain");
@@ -4439,10 +4439,10 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
// A sibling call is one where we're under the usual C ABI and not planning
// to change that but can still do a tail call:
- if (!TailCallOpt && IsTailCall)
+ if (!TailCallOpt && CLI.getIsTailCall())
IsSibCall = true;
- if (IsTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
}
@@ -4553,7 +4553,7 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
SDValue PtrOff = DAG.getConstant(Offset, DL, PtrVT);
MaybeAlign Alignment;
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
ISD::ArgFlagsTy Flags = Outs[i].Flags;
unsigned OpSize = Flags.isByVal() ? Flags.getByValSize()
: VA.getValVT().getStoreSize();
@@ -4653,7 +4653,7 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
// the frame up *after* the call, however in the ABI-changing tail-call case
// we've carefully laid out the parameters so that when sp is reset they'll be
// in the correct location.
- if (IsTailCall && !IsSibCall) {
+ if (CLI.getIsTailCall() && !IsSibCall) {
Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, DL);
InGlue = Chain.getValue(1);
}
@@ -4667,7 +4667,7 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
Ops.push_back(Callee);
Ops.push_back(DAG.getTargetGlobalAddress(GV, DL, MVT::i64));
} else {
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
// isEligibleForTailCallOptimization considered whether the call target is
// divergent, but we may still end up with a uniform value in a VGPR.
// Insert a readfirstlane just in case.
@@ -4685,7 +4685,7 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
Ops.push_back(DAG.getTargetConstant(0, DL, MVT::i64));
}
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
// Each tail call may have to adjust the stack by a different amount, so
// this information must travel along with the operation for eventual
// consumption by emitEpilogue.
@@ -4721,7 +4721,7 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
// If we're doing a tall call, use a TC_RETURN here rather than an
// actual call instruction.
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
MFI.setHasTailCall();
unsigned OPC = AMDGPUISD::TC_RETURN;
switch (CallConv) {
@@ -4741,13 +4741,13 @@ SDValue SITargetLowering::LowerCall(CallLoweringInfo &CLI,
OPC = AMDGPUISD::TC_RETURN_GFX_WholeWave;
SDValue Ret = DAG.getNode(OPC, DL, MVT::Other, Ops);
- DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.getNoMerge());
return Ret;
}
// Returns a chain and a flag for retval copy to use.
SDValue Call = DAG.getNode(AMDGPUISD::CALL, DL, {MVT::Other, MVT::Glue}, Ops);
- DAG.addNoMergeSiteInfo(Call.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Call.getNode(), CLI.getNoMerge());
Chain = Call.getValue(0);
InGlue = Call.getValue(1);
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h
index 4fffb7bd2d120..b092547e0fc93 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h
@@ -437,18 +437,16 @@ class SITargetLowering final : public AMDGPUTargetLowering {
const SmallVectorImpl<MachineBasicBlock *> &Exits) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
- bool CanLowerReturn(CallingConv::ID CallConv,
- MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
@@ -462,18 +460,17 @@ class SITargetLowering final : public AMDGPUTargetLowering {
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &DL, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
- SDValue ThisVal) const;
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
+ bool isThisReturn, SDValue ThisVal) const;
bool mayBeEmittedAsTailCall(const CallInst *) const override;
bool isEligibleForTailCallOptimization(
- SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const;
+ SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ llvm::ArrayRef<ISD::InputArg> Ins, SelectionDAG &DAG) const;
SDValue LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
@@ -643,7 +640,7 @@ class SITargetLowering final : public AMDGPUTargetLowering {
void allocatePreloadKernArgSGPRs(CCState &CCInfo,
SmallVectorImpl<CCValAssign> &ArgLocs,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ llvm::ArrayRef<ISD::InputArg> Ins,
MachineFunction &MF,
const SIRegisterInfo &TRI,
SIMachineFunctionInfo &Info) const;
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
index 1cef1223c246c..edac3325e6b13 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
@@ -48,17 +48,14 @@ bool SIMachineFunctionInfo::MFMAVGPRForm = false;
SIMachineFunctionInfo::SIMachineFunctionInfo(const Function &F,
const GCNSubtarget *STI)
: AMDGPUMachineFunctionInfo(F, *STI), Mode(F, *STI),
- GWSResourcePSV(getTM(STI)), UserSGPRInfo(F, *STI), WorkGroupIDX(false),
- WorkGroupIDY(false), WorkGroupIDZ(false), WorkGroupInfo(false),
- LDSKernelId(false), PrivateSegmentWaveByteOffset(false),
- WorkItemIDX(false), WorkItemIDY(false), WorkItemIDZ(false),
- ImplicitArgPtr(false), GITPtrHigh(0xffffffff), HighBitsOf32BitAddress(0),
- IsWholeWaveFunction(F.getCallingConv() ==
- CallingConv::AMDGPU_Gfx_WholeWave) {
+ GWSResourcePSV(getTM(STI)), UserSGPRInfo(F, *STI), GITPtrHigh(0xffffffff),
+ HighBitsOf32BitAddress(0) {
+ setIsWholeWaveFunction(F.getCallingConv() ==
+ CallingConv::AMDGPU_Gfx_WholeWave);
const GCNSubtarget &ST = *STI;
FlatWorkGroupSizes = ST.getFlatWorkGroupSizes(F);
WavesPerEU = ST.getWavesPerEU(F);
- MaxNumWorkGroups = AMDGPU::getMaxNumWorkGroups(F);
+ MaxNumWorkGroups.assign(AMDGPU::getMaxNumWorkGroups(F));
assert(MaxNumWorkGroups.size() == 3);
DynamicVGPRBlockSize = AMDGPU::getDynamicVGPRBlockSize(F);
@@ -71,8 +68,8 @@ SIMachineFunctionInfo::SIMachineFunctionInfo(const Function &F,
CC == CallingConv::SPIR_KERNEL;
if (IsKernel) {
- WorkGroupIDX = true;
- WorkItemIDX = true;
+ setWorkGroupIDX(true);
+ setWorkItemIDXFlag(true);
} else if (CC == CallingConv::AMDGPU_PS) {
PSInputAddr = AMDGPU::getInitialPSInputAddr(F);
}
@@ -107,9 +104,9 @@ SIMachineFunctionInfo::SIMachineFunctionInfo(const Function &F,
if (!F.hasFnAttribute("amdgpu-no-implicitarg-ptr") &&
!AMDGPU::isChainCC(CC))
- ImplicitArgPtr = true;
+ setImplicitArgPtr(true);
} else {
- ImplicitArgPtr = false;
+ setImplicitArgPtr(false);
MaxKernArgAlign =
std::max(ST.getAlignmentForImplicitArgPtr(), MaxKernArgAlign);
}
@@ -119,41 +116,41 @@ SIMachineFunctionInfo::SIMachineFunctionInfo(const Function &F,
ST.hasArchitectedSGPRs())) {
if (IsKernel || !F.hasFnAttribute("amdgpu-no-workgroup-id-x") ||
!F.hasFnAttribute("amdgpu-no-cluster-id-x"))
- WorkGroupIDX = true;
+ setWorkGroupIDX(true);
if (!F.hasFnAttribute("amdgpu-no-workgroup-id-y") ||
!F.hasFnAttribute("amdgpu-no-cluster-id-y"))
- WorkGroupIDY = true;
+ setWorkGroupIDY(true);
if (!F.hasFnAttribute("amdgpu-no-workgroup-id-z") ||
!F.hasFnAttribute("amdgpu-no-cluster-id-z"))
- WorkGroupIDZ = true;
+ setWorkGroupIDZ(true);
}
if (!AMDGPU::isGraphics(CC)) {
if (IsKernel || !F.hasFnAttribute("amdgpu-no-workitem-id-x"))
- WorkItemIDX = true;
+ setWorkItemIDXFlag(true);
if (!F.hasFnAttribute("amdgpu-no-workitem-id-y") &&
ST.getMaxWorkitemID(F, 1) != 0)
- WorkItemIDY = true;
+ setWorkItemIDYFlag(true);
if (!F.hasFnAttribute("amdgpu-no-workitem-id-z") &&
ST.getMaxWorkitemID(F, 2) != 0)
- WorkItemIDZ = true;
+ setWorkItemIDZFlag(true);
if (!IsKernel && !F.hasFnAttribute("amdgpu-no-lds-kernel-id"))
- LDSKernelId = true;
+ setLDSKernelId(true);
}
if (isEntryFunction()) {
// X, XY, and XYZ are the only supported combinations, so make sure Y is
// enabled if Z is.
- if (WorkItemIDZ)
- WorkItemIDY = true;
+ if (getWorkItemIDZFlag())
+ setWorkItemIDYFlag(true);
if (!ST.hasArchitectedFlatScratch()) {
- PrivateSegmentWaveByteOffset = true;
+ setPrivateSegmentWaveByteOffsetFlag(true);
// HS and GS always have the scratch wave offset in SGPR5 on GFX9.
if (ST.getGeneration() >= AMDGPUSubtarget::GFX9 &&
@@ -498,7 +495,7 @@ bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
// This has already been allocated.
if (!Spill.Lanes.empty())
- return Spill.FullyAllocated;
+ return Spill.isFullyAllocated();
unsigned Size = FrameInfo.getObjectSize(FI);
unsigned NumLanes = Size / 4;
@@ -510,7 +507,7 @@ bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
auto &SpillRegs = isAGPRtoVGPR ? SpillAGPR : SpillVGPR;
const SIRegisterInfo *TRI = ST.getRegisterInfo();
- Spill.FullyAllocated = true;
+ Spill.setFullyAllocated(true);
// FIXME: Move allocation logic out of MachineFunctionInfo and initialize
// once.
@@ -538,7 +535,7 @@ bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
});
if (NextSpillReg == Regs.end()) { // Registers exhausted
- Spill.FullyAllocated = false;
+ Spill.setFullyAllocated(false);
break;
}
@@ -548,7 +545,7 @@ bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
Spill.Lanes[I] = *NextSpillReg++;
}
- return Spill.FullyAllocated;
+ return Spill.isFullyAllocated();
}
bool SIMachineFunctionInfo::removeDeadFrameIndices(
@@ -587,7 +584,7 @@ bool SIMachineFunctionInfo::removeDeadFrameIndices(
}
for (auto &R : VGPRToAGPRSpills) {
- if (R.second.IsDead)
+ if (R.second.isDead())
MFI.RemoveStackObject(R.first);
}
@@ -790,14 +787,14 @@ bool SIMachineFunctionInfo::initializeBaseYamlFields(
IsEntryFunction = YamlMFI.IsEntryFunction;
MemoryBound = YamlMFI.MemoryBound;
WaveLimiter = YamlMFI.WaveLimiter;
- HasSpilledSGPRs = YamlMFI.HasSpilledSGPRs;
- HasSpilledVGPRs = YamlMFI.HasSpilledVGPRs;
- HasNoWWMPoolSGPRSpillFallback = YamlMFI.HasNoWWMPoolSGPRSpillFallback;
+ setHasSpilledSGPRsFlag(YamlMFI.HasSpilledSGPRs);
+ setHasSpilledVGPRsFlag(YamlMFI.HasSpilledVGPRs);
+ setHasNoWWMPoolSGPRSpillFallback(YamlMFI.HasNoWWMPoolSGPRSpillFallback);
NumWaveDispatchSGPRs = YamlMFI.NumWaveDispatchSGPRs;
NumWaveDispatchVGPRs = YamlMFI.NumWaveDispatchVGPRs;
BytesInStackArgArea = YamlMFI.BytesInStackArgArea;
ReturnsVoid = YamlMFI.ReturnsVoid;
- IsWholeWaveFunction = YamlMFI.IsWholeWaveFunction;
+ setIsWholeWaveFunction(YamlMFI.IsWholeWaveFunction);
MinNumAGPRs = YamlMFI.MinNumAGPRs;
// This can also be set by the function attribute, MFI has higher precedence
// though.
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
index 359fc36dbcc71..2cee8104297a4 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
@@ -22,6 +22,7 @@
#include "SIModeRegisterDefaults.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Support/raw_ostream.h"
@@ -473,7 +474,10 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
const AMDGPUGWSResourcePseudoSourceValue GWSResourcePSV;
// Default/requested number of work groups for the function.
- SmallVector<unsigned> MaxNumWorkGroups = {0, 0, 0};
+ llvm::SmallVectorWithFlags<
+ unsigned,
+ llvm::CalculateSmallVectorDefaultInlinedElements<unsigned>::value, 4>
+ MaxNumWorkGroups = {0, 0, 0};
// Requested cluster dimensions.
AMDGPU::ClusterDimsAttr ClusterDims;
@@ -485,10 +489,24 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
unsigned NumWaveDispatchSGPRs = 0;
unsigned NumWaveDispatchVGPRs = 0;
- bool HasSpilledSGPRs = false;
- bool HasSpilledVGPRs = false;
- bool HasNonSpillStackObjects = false;
- bool IsStackRealigned = false;
+ bool getHasSpilledSGPRsFlag() const { return MaxNumWorkGroups.getFlag(0); }
+ void setHasSpilledSGPRsFlag(bool Value) {
+ MaxNumWorkGroups.setFlag(0, Value);
+ }
+ bool getHasSpilledVGPRsFlag() const { return MaxNumWorkGroups.getFlag(1); }
+ void setHasSpilledVGPRsFlag(bool Value) {
+ MaxNumWorkGroups.setFlag(1, Value);
+ }
+ bool getHasNonSpillStackObjectsFlag() const {
+ return MaxNumWorkGroups.getFlag(2);
+ }
+ void setHasNonSpillStackObjectsFlag(bool Value) {
+ MaxNumWorkGroups.setFlag(2, Value);
+ }
+ bool getIsStackRealignedFlag() const { return MaxNumWorkGroups.getFlag(3); }
+ void setIsStackRealignedFlag(bool Value) {
+ MaxNumWorkGroups.setFlag(3, Value);
+ }
unsigned NumSpilledSGPRs = 0;
unsigned NumSpilledVGPRs = 0;
@@ -504,20 +522,60 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
GCNUserSGPRUsageInfo UserSGPRInfo;
// Feature bits required for inputs passed in system SGPRs.
- bool WorkGroupIDX : 1; // Always initialized.
- bool WorkGroupIDY : 1;
- bool WorkGroupIDZ : 1;
- bool WorkGroupInfo : 1;
- bool LDSKernelId : 1;
- bool PrivateSegmentWaveByteOffset : 1;
-
- bool WorkItemIDX : 1; // Always initialized.
- bool WorkItemIDY : 1;
- bool WorkItemIDZ : 1;
+ bool getWorkGroupIDX() const { return PrologEpilogSGPRSpills.getFlag(0); }
+ bool setWorkGroupIDX(bool Value) {
+ PrologEpilogSGPRSpills.setFlag(0, Value);
+ return Value;
+ } // Always initialized.
+ bool getWorkGroupIDY() const { return PrologEpilogSGPRSpills.getFlag(1); }
+ bool setWorkGroupIDY(bool Value) {
+ PrologEpilogSGPRSpills.setFlag(1, Value);
+ return Value;
+ }
+ bool getWorkGroupIDZ() const { return PrologEpilogSGPRSpills.getFlag(2); }
+ bool setWorkGroupIDZ(bool Value) {
+ PrologEpilogSGPRSpills.setFlag(2, Value);
+ return Value;
+ }
+ bool getWorkGroupInfo() const { return PrologEpilogSGPRSpills.getFlag(3); }
+ void setWorkGroupInfo(bool Value) {
+ PrologEpilogSGPRSpills.setFlag(3, Value);
+ }
+ bool getLDSKernelId() const { return SpillPhysVGPRs.getFlag(0); }
+ bool setLDSKernelId(bool Value) {
+ SpillPhysVGPRs.setFlag(0, Value);
+ return Value;
+ }
+ bool getPrivateSegmentWaveByteOffsetFlag() const {
+ return SpillPhysVGPRs.getFlag(1);
+ }
+ void setPrivateSegmentWaveByteOffsetFlag(bool Value) {
+ SpillPhysVGPRs.setFlag(1, Value);
+ }
+
+ bool getWorkItemIDXFlag() const { return SpillPhysVGPRs.getFlag(2); }
+ bool setWorkItemIDXFlag(bool Value) {
+ SpillPhysVGPRs.setFlag(2, Value);
+ return Value;
+ } // Always initialized.
+ bool getWorkItemIDYFlag() const { return SpillPhysVGPRs.getFlag(3); }
+ bool setWorkItemIDYFlag(bool Value) {
+ SpillPhysVGPRs.setFlag(3, Value);
+ return Value;
+ }
+ bool getWorkItemIDZFlag() const { return SpillVGPRs.getFlag(0); }
+ bool setWorkItemIDZFlag(bool Value) {
+ SpillVGPRs.setFlag(0, Value);
+ return Value;
+ }
// Pointer to where the ABI inserts special kernel arguments separate from the
// user arguments. This is an offset from the KernargSegmentPtr.
- bool ImplicitArgPtr : 1;
+ bool getImplicitArgPtr() const { return SpillVGPRs.getFlag(1); }
+ bool setImplicitArgPtr(bool Value) {
+ SpillVGPRs.setFlag(1, Value);
+ return Value;
+ }
/// Minimum number of AGPRs required to allocate in the function. Only
/// relevant for gfx90a-gfx950. For gfx908, this should be infinite.
@@ -552,9 +610,11 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
static bool MFMAVGPRForm;
struct VGPRSpillToAGPR {
- SmallVector<MCPhysReg, 32> Lanes;
- bool FullyAllocated = false;
- bool IsDead = false;
+ SmallVectorWithFlags<MCPhysReg, 32, 2> Lanes;
+ bool isFullyAllocated() const { return Lanes.getFlag(0); }
+ void setFullyAllocated(bool Value) { Lanes.setFlag(0, Value); }
+ bool isDead() const { return Lanes.getFlag(1); }
+ void setIsDead(bool Value) { Lanes.setFlag(1, Value); }
};
private:
@@ -568,8 +628,8 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
SGPRSpillsToPhysicalVGPRLanes;
unsigned NumVirtualVGPRSpillLanes = 0;
unsigned NumPhysicalVGPRSpillLanes = 0;
- SmallVector<Register, 2> SpillVGPRs;
- SmallVector<Register, 2> SpillPhysVGPRs;
+ llvm::SmallVectorWithFlags<Register, 2, 4> SpillVGPRs;
+ llvm::SmallVectorWithFlags<Register, 2, 4> SpillPhysVGPRs;
using WWMSpillsMap = MapVector<Register, int>;
// To track the registers used in instructions that can potentially modify the
// inactive lanes. The WWM instructions and the writelane instructions for
@@ -591,7 +651,8 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
// the serialization easier.
ReservedRegSet WWMReservedRegs;
- bool IsWholeWaveFunction = false;
+ bool getIsWholeWaveFunction() const { return SpillVGPRs.getFlag(2); }
+ void setIsWholeWaveFunction(bool Value) { SpillVGPRs.setFlag(2, Value); }
using PrologEpilogSGPRSpill =
std::pair<Register, PrologEpilogSGPRSaveRestoreInfo>;
@@ -599,7 +660,8 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
// frame lowering. Even though the SGPR spills are handled during
// SILowerSGPRSpills pass, some special handling needed later during the
// PrologEpilogInserter.
- SmallVector<PrologEpilogSGPRSpill, 3> PrologEpilogSGPRSpills;
+ llvm::SmallVectorWithFlags<PrologEpilogSGPRSpill, 3, 4>
+ PrologEpilogSGPRSpills;
// To save/restore EXEC MASK around WWM spills and copies.
Register SGPRForEXECCopy;
@@ -619,7 +681,12 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
// Ordinary SGPR spills fell back to memory because no WWM VGPR pool was
// available. This path may require additional nested VGPR scavenging slots
// during frame-index elimination.
- bool HasNoWWMPoolSGPRSpillFallback = false;
+ bool getHasNoWWMPoolSGPRSpillFallback() const {
+ return SpillVGPRs.getFlag(3);
+ }
+ void setHasNoWWMPoolSGPRSpillFallback(bool Value) {
+ SpillVGPRs.setFlag(3, Value);
+ }
// Map each VGPR CSR to the mask needed to save and restore it using block
// load/store instructions. Only used if the subtarget feature for VGPR block
@@ -703,7 +770,7 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
return WWMReservedRegs.contains(Reg);
}
- bool isWholeWaveFunction() const { return IsWholeWaveFunction; }
+ bool isWholeWaveFunction() const { return getIsWholeWaveFunction(); }
ArrayRef<PrologEpilogSGPRSpill> getPrologEpilogSGPRSpills() const {
assert(is_sorted(PrologEpilogSGPRSpills, llvm::less_first()));
@@ -839,7 +906,7 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
void setVGPRToAGPRSpillDead(int FrameIndex) {
auto I = VGPRToAGPRSpills.find(FrameIndex);
if (I != VGPRToAGPRSpills.end())
- I->second.IsDead = true;
+ I->second.setIsDead(true);
}
// To bring the allocated WWM registers in \p WWMVGPRs to the lowest available
@@ -861,9 +928,11 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
int getScavengeFI(MachineFrameInfo &MFI, const SIRegisterInfo &TRI);
std::optional<int> getOptionalScavengeFI() const { return ScavengeFI; }
- void setNoWWMPoolSGPRSpillFallback() { HasNoWWMPoolSGPRSpillFallback = true; }
+ void setNoWWMPoolSGPRSpillFallback() {
+ setHasNoWWMPoolSGPRSpillFallback(true);
+ }
bool hasNoWWMPoolSGPRSpillFallback() const {
- return HasNoWWMPoolSGPRSpillFallback;
+ return getHasNoWWMPoolSGPRSpillFallback();
}
unsigned getBytesInStackArgArea() const {
@@ -933,7 +1002,7 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
return ArgInfo.WorkGroupInfo.getRegister();
}
- bool hasLDSKernelId() const { return LDSKernelId; }
+ bool hasLDSKernelId() const { return getLDSKernelId(); }
// Add special VGPR inputs
void setWorkItemIDX(ArgDescriptor Arg) {
@@ -959,41 +1028,25 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
ArgInfo.PrivateSegmentWaveByteOffset = ArgDescriptor::createRegister(Reg);
}
- bool hasWorkGroupIDX() const {
- return WorkGroupIDX;
- }
+ bool hasWorkGroupIDX() const { return getWorkGroupIDX(); }
- bool hasWorkGroupIDY() const {
- return WorkGroupIDY;
- }
+ bool hasWorkGroupIDY() const { return getWorkGroupIDY(); }
- bool hasWorkGroupIDZ() const {
- return WorkGroupIDZ;
- }
+ bool hasWorkGroupIDZ() const { return getWorkGroupIDZ(); }
- bool hasWorkGroupInfo() const {
- return WorkGroupInfo;
- }
+ bool hasWorkGroupInfo() const { return getWorkGroupInfo(); }
bool hasPrivateSegmentWaveByteOffset() const {
- return PrivateSegmentWaveByteOffset;
+ return getPrivateSegmentWaveByteOffsetFlag();
}
- bool hasWorkItemIDX() const {
- return WorkItemIDX;
- }
+ bool hasWorkItemIDX() const { return getWorkItemIDXFlag(); }
- bool hasWorkItemIDY() const {
- return WorkItemIDY;
- }
+ bool hasWorkItemIDY() const { return getWorkItemIDYFlag(); }
- bool hasWorkItemIDZ() const {
- return WorkItemIDZ;
- }
+ bool hasWorkItemIDZ() const { return getWorkItemIDZFlag(); }
- bool hasImplicitArgPtr() const {
- return ImplicitArgPtr;
- }
+ bool hasImplicitArgPtr() const { return getImplicitArgPtr(); }
AMDGPUFunctionArgInfo &getArgInfo() {
return ArgInfo;
@@ -1094,36 +1147,26 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
return ArgInfo.ImplicitBufferPtr.getRegister();
}
- bool hasSpilledSGPRs() const {
- return HasSpilledSGPRs;
- }
+ bool hasSpilledSGPRs() const { return getHasSpilledSGPRsFlag(); }
- void setHasSpilledSGPRs(bool Spill = true) {
- HasSpilledSGPRs = Spill;
- }
+ void setHasSpilledSGPRs(bool Spill = true) { setHasSpilledSGPRsFlag(Spill); }
- bool hasSpilledVGPRs() const {
- return HasSpilledVGPRs;
- }
+ bool hasSpilledVGPRs() const { return getHasSpilledVGPRsFlag(); }
- void setHasSpilledVGPRs(bool Spill = true) {
- HasSpilledVGPRs = Spill;
- }
+ void setHasSpilledVGPRs(bool Spill = true) { setHasSpilledVGPRsFlag(Spill); }
bool hasNonSpillStackObjects() const {
- return HasNonSpillStackObjects;
+ return getHasNonSpillStackObjectsFlag();
}
void setHasNonSpillStackObjects(bool StackObject = true) {
- HasNonSpillStackObjects = StackObject;
+ setHasNonSpillStackObjectsFlag(StackObject);
}
- bool isStackRealigned() const {
- return IsStackRealigned;
- }
+ bool isStackRealigned() const { return getIsStackRealignedFlag(); }
void setIsStackRealigned(bool Realigned = true) {
- IsStackRealigned = Realigned;
+ setIsStackRealignedFlag(Realigned);
}
unsigned getNumSpilledSGPRs() const {
@@ -1241,7 +1284,9 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunctionInfo,
}
/// \returns Default/requested number of work groups for this function.
- SmallVector<unsigned> getMaxNumWorkGroups() const { return MaxNumWorkGroups; }
+ SmallVector<unsigned> getMaxNumWorkGroups() const {
+ return {MaxNumWorkGroups.begin(), MaxNumWorkGroups.end()};
+ }
unsigned getMaxNumWorkGroupsX() const { return MaxNumWorkGroups[0]; }
unsigned getMaxNumWorkGroupsY() const { return MaxNumWorkGroups[1]; }
diff --git a/llvm/lib/Target/AMDGPU/SIModeRegister.cpp b/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
index 3599b4e1ad578..ba090b6f385d1 100644
--- a/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
+++ b/llvm/lib/Target/AMDGPU/SIModeRegister.cpp
@@ -15,6 +15,7 @@
//
#include "AMDGPU.h"
#include "GCNSubtarget.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include <optional>
@@ -100,11 +101,13 @@ class BlockData {
// Call and return sites, each paired with the block local mode changes that
// precede it. Phase 3 merges the pair with Pred to get the mode at the site.
- SmallVector<std::pair<MachineInstr *, Status>, 2> BoundarySites;
+ llvm::SmallVectorWithFlags<std::pair<MachineInstr *, Status>, 2>
+ BoundarySites;
// A flag to indicate whether an Exit value has been set (we can't tell by
// examining the Exit value itself as all values may be valid results).
- bool ExitSet = false;
+ bool getExitSet() const { return BoundarySites.getFlag(0); }
+ void setExitSet(bool Value) { BoundarySites.setFlag(0, Value); }
BlockData() = default;
};
@@ -446,7 +449,7 @@ void SIModeRegister::processBlockPhase2(MachineBasicBlock &MBB,
if ((ThisBlock == PredBlock) && (std::next(P) == E)) {
BlockInfo[ThisBlock]->Pred = DefaultStatus;
ExitSet = true;
- } else if (BlockInfo[PredBlock]->ExitSet) {
+ } else if (BlockInfo[PredBlock]->getExitSet()) {
BlockInfo[ThisBlock]->Pred = BlockInfo[PredBlock]->Exit;
ExitSet = true;
} else if (PredBlock != ThisBlock)
@@ -455,8 +458,8 @@ void SIModeRegister::processBlockPhase2(MachineBasicBlock &MBB,
for (P = std::next(P); P != E; P = std::next(P)) {
MachineBasicBlock *Pred = *P;
unsigned PredBlock = Pred->getNumber();
- if (BlockInfo[PredBlock]->ExitSet) {
- if (BlockInfo[ThisBlock]->ExitSet) {
+ if (BlockInfo[PredBlock]->getExitSet()) {
+ if (BlockInfo[ThisBlock]->getExitSet()) {
BlockInfo[ThisBlock]->Pred =
BlockInfo[ThisBlock]->Pred.intersect(BlockInfo[PredBlock]->Exit);
} else {
@@ -476,7 +479,10 @@ void SIModeRegister::processBlockPhase2(MachineBasicBlock &MBB,
for (MachineBasicBlock *Succ : MBB.successors())
Phase2List.push(Succ);
}
- BlockInfo[ThisBlock]->ExitSet = ExitSet;
+ [&] {
+ auto PackedFlagValue = ExitSet;
+ return BlockInfo[ThisBlock]->setExitSet(PackedFlagValue);
+ }();
if (RevisitRequired)
Phase2List.push(&MBB);
}
diff --git a/llvm/lib/Target/ARC/ARCISelLowering.cpp b/llvm/lib/Target/ARC/ARCISelLowering.cpp
index e3704fcf95051..6cbc923792a0e 100644
--- a/llvm/lib/Target/ARC/ARCISelLowering.cpp
+++ b/llvm/lib/Target/ARC/ARCISelLowering.cpp
@@ -248,16 +248,15 @@ SDValue ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &dl = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
- bool &IsTailCall = CLI.IsTailCall;
+ bool IsVarArg = CLI.getIsVarArg();
- IsTailCall = false; // Do not support tail calls yet.
+ CLI.setIsTailCall(false); // Do not support tail calls yet.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
@@ -320,7 +319,7 @@ SDValue ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SDValue Store =
DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
MemOpChains.push_back(Store);
- IsTailCall = false;
+ CLI.setIsTailCall(false);
}
}
@@ -382,7 +381,7 @@ SDValue ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Handle result values, copying them out of physregs into vregs that we
// return.
- if (IsTailCall)
+ if (CLI.getIsTailCall())
return Chain;
return lowerCallResult(Chain, Glue, RVLocs, dl, DAG, InVals);
}
@@ -452,8 +451,8 @@ struct ArgDataPair {
/// ARC formal arguments implementation
SDValue ARCTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
switch (CallConv) {
default:
llvm_unreachable("Unsupported calling convention");
@@ -467,7 +466,7 @@ SDValue ARCTargetLowering::LowerFormalArguments(
/// operations for argument places on the stack.
SDValue ARCTargetLowering::LowerCallArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -612,10 +611,11 @@ SDValue ARCTargetLowering::LowerCallArguments(
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
-bool ARCTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool ARCTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
@@ -625,12 +625,12 @@ bool ARCTargetLowering::CanLowerReturn(
return true;
}
-SDValue
-ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &dl, SelectionDAG &DAG) const {
+SDValue ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &dl,
+ SelectionDAG &DAG) const {
auto *AFI = DAG.getMachineFunction().getInfo<ARCFunctionInfo>();
MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
diff --git a/llvm/lib/Target/ARC/ARCISelLowering.h b/llvm/lib/Target/ARC/ARCISelLowering.h
index d0b3eb898eae9..5b402901dc136 100644
--- a/llvm/lib/Target/ARC/ARCISelLowering.h
+++ b/llvm/lib/Target/ARC/ARCISelLowering.h
@@ -49,8 +49,7 @@ class ARCTargetLowering : public TargetLowering {
// Lower Operand helpers
SDValue LowerCallArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
// Lower Operand specifics
@@ -63,8 +62,7 @@ class ARCTargetLowering : public TargetLowering {
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
@@ -72,13 +70,12 @@ class ARCTargetLowering : public TargetLowering {
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
SelectionDAG &DAG) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> ArgsFlags,
LLVMContext &Context, const Type *RetTy) const override;
bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index 9bbd029495a79..18fb41c0ec8cf 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -52,7 +52,7 @@ using namespace llvm;
ARMAsmPrinter::ARMAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer), ID), AFI(nullptr), MCP(nullptr),
- InConstantPool(false), OptimizationGoals(-1) {}
+ OptimizationGoals(-1) {}
const ARMBaseTargetMachine &ARMAsmPrinter::getTM() const {
return static_cast<const ARMBaseTargetMachine &>(TM);
@@ -61,9 +61,9 @@ const ARMBaseTargetMachine &ARMAsmPrinter::getTM() const {
void ARMAsmPrinter::emitFunctionBodyEnd() {
// Make sure to terminate any constant pools that were at the end
// of the function.
- if (!InConstantPool)
+ if (!getInConstantPool())
return;
- InConstantPool = false;
+ setInConstantPool(false);
OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
}
@@ -1987,9 +1987,9 @@ void ARMAsmPrinter::emitInstruction(const MachineInstr *MI) {
ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
// If we just ended a constant pool, mark it as such.
- if (InConstantPool && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
+ if (getInConstantPool() && MI->getOpcode() != ARM::CONSTPOOL_ENTRY) {
OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
- InConstantPool = false;
+ setInConstantPool(false);
}
// Emit unwinding stuff for frame-related instructions
@@ -2367,9 +2367,9 @@ void ARMAsmPrinter::emitInstruction(const MachineInstr *MI) {
unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
// If this is the first entry of the pool, mark it.
- if (!InConstantPool) {
+ if (!getInConstantPool()) {
OutStreamer->emitDataRegion(MCDR_DataRegion);
- InConstantPool = true;
+ setInConstantPool(true);
}
OutStreamer->emitLabel(GetCPISymbol(LabelId));
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.h b/llvm/lib/Target/ARM/ARMAsmPrinter.h
index 1d35b3c445958..fbd0f3dd0ad2b 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.h
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIB_TARGET_ARM_ARMASMPRINTER_H
#define LLVM_LIB_TARGET_ARM_ARMASMPRINTER_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/Target/TargetMachine.h"
@@ -43,11 +44,13 @@ class LLVM_LIBRARY_VISIBILITY ARMAsmPrinter : public AsmPrinter {
/// InConstantPool - Maintain state when emitting a sequence of constant
/// pool entries so we can properly mark them as data regions.
- bool InConstantPool;
+ bool getInConstantPool() const { return ThumbIndirectPads.getFlag(0); }
+ void setInConstantPool(bool Value) { ThumbIndirectPads.setFlag(0, Value); }
/// ThumbIndirectPads - These maintain a per-function list of jump pad
/// labels used for ARMv4t thumb code to make register indirect calls.
- SmallVector<std::pair<unsigned, MCSymbol*>, 4> ThumbIndirectPads;
+ llvm::SmallVectorWithFlags<std::pair<unsigned, MCSymbol *>, 4>
+ ThumbIndirectPads;
/// OptimizationGoals - Maintain a combined optimization goal for all
/// functions in a module: one of Tag_ABI_optimization_goals values,
diff --git a/llvm/lib/Target/ARM/ARMBasicBlockInfo.cpp b/llvm/lib/Target/ARM/ARMBasicBlockInfo.cpp
index afbbe4924fb6c..97edc21683065 100644
--- a/llvm/lib/Target/ARM/ARMBasicBlockInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBasicBlockInfo.cpp
@@ -53,9 +53,9 @@ void ARMBasicBlockUtils::computeBlockSize(MachineBasicBlock *MBB) {
// For inline asm, getInstSizeInBytes returns a conservative estimate.
// The actual size may be smaller, but still a multiple of the instr size.
if (I.isInlineAsm())
- BBI.Unalign = isThumb ? 1 : 2;
+ BBI.Unalign = getIsThumb() ? 1 : 2;
// Also consider instructions that may be shrunk later.
- else if (isThumb && mayOptimizeThumb2Instruction(&I))
+ else if (getIsThumb() && mayOptimizeThumb2Instruction(&I))
BBI.Unalign = 1;
}
@@ -90,7 +90,7 @@ unsigned ARMBasicBlockUtils::getOffsetOf(MachineInstr *MI) const {
bool ARMBasicBlockUtils::isBBInRange(MachineInstr *MI,
MachineBasicBlock *DestBB,
unsigned MaxDisp) const {
- unsigned PCAdj = isThumb ? 4 : 8;
+ unsigned PCAdj = getIsThumb() ? 4 : 8;
unsigned BrOffset = getOffsetOf(MI) + PCAdj;
unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
diff --git a/llvm/lib/Target/ARM/ARMBasicBlockInfo.h b/llvm/lib/Target/ARM/ARMBasicBlockInfo.h
index daf8f9b4b8361..abaf2cd88eee5 100644
--- a/llvm/lib/Target/ARM/ARMBasicBlockInfo.h
+++ b/llvm/lib/Target/ARM/ARMBasicBlockInfo.h
@@ -15,6 +15,7 @@
#include "ARMBaseInstrInfo.h"
#include "ARMMachineFunctionInfo.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cstdint>
@@ -22,7 +23,6 @@
namespace llvm {
struct BasicBlockInfo;
-using BBInfoVector = SmallVectorImpl<BasicBlockInfo>;
/// UnknownPadding - Return the worst case padding that could result from
/// unknown offset bits. This does not include alignment padding caused by
@@ -110,15 +110,16 @@ class ARMBasicBlockUtils {
private:
MachineFunction &MF;
- bool isThumb = false;
+ bool getIsThumb() const { return BBInfo.getFlag(0); }
+ void setIsThumb(bool Value) { BBInfo.setFlag(0, Value); }
const ARMBaseInstrInfo *TII = nullptr;
- SmallVector<BasicBlockInfo, 8> BBInfo;
+ llvm::SmallVectorWithFlags<BasicBlockInfo, 8> BBInfo;
public:
ARMBasicBlockUtils(MachineFunction &MF) : MF(MF) {
TII =
static_cast<const ARMBaseInstrInfo*>(MF.getSubtarget().getInstrInfo());
- isThumb = MF.getInfo<ARMFunctionInfo>()->isThumbFunction();
+ setIsThumb(MF.getInfo<ARMFunctionInfo>()->isThumbFunction());
}
void computeAllBlockSizes() {
@@ -150,8 +151,7 @@ class ARMBasicBlockUtils {
void clear() { BBInfo.clear(); }
- BBInfoVector &getBBInfo() { return BBInfo; }
-
+ auto &getBBInfo() { return BBInfo; }
};
} // end namespace llvm
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp
index 713f4fccb9e92..ce0473e92635e 100644
--- a/llvm/lib/Target/ARM/ARMCallLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp
@@ -483,7 +483,7 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &
bool IsDirect = !Info.Callee.isReg();
auto CallOpcode = getCallOpcode(MF, STI, IsDirect);
auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode);
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::MIFlag::NoMerge);
bool IsThumb = STI.isThumb();
diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
index cacbc3e2d69c9..e86950259ab3f 100644
--- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -24,6 +24,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/LivePhysRegs.h"
@@ -203,7 +204,7 @@ namespace {
SmallVector<MachineInstr*, 4> PushPopMIs;
/// T2JumpTables - Keep track of all the Thumb2 jumptable instructions.
- SmallVector<MachineInstr*, 4> T2JumpTables;
+ llvm::SmallVectorWithFlags<MachineInstr *, 4, 4> T2JumpTables;
MachineFunction *MF;
MachineConstantPool *MCP;
@@ -211,10 +212,18 @@ namespace {
const ARMSubtarget *STI;
ARMFunctionInfo *AFI;
MachineDominatorTree *DT = nullptr;
- bool isThumb;
- bool isThumb1;
- bool isThumb2;
- bool isPositionIndependentOrROPI;
+ bool getIsThumb() const { return T2JumpTables.getFlag(0); }
+ void setIsThumb(bool Value) { T2JumpTables.setFlag(0, Value); }
+ bool getIsThumb1() const { return T2JumpTables.getFlag(1); }
+ void setIsThumb1(bool Value) { T2JumpTables.setFlag(1, Value); }
+ bool getIsThumb2() const { return T2JumpTables.getFlag(2); }
+ void setIsThumb2(bool Value) { T2JumpTables.setFlag(2, Value); }
+ bool getIsPositionIndependentOrROPI() const {
+ return T2JumpTables.getFlag(3);
+ }
+ void setIsPositionIndependentOrROPI(bool Value) {
+ T2JumpTables.setFlag(3, Value);
+ }
public:
static char ID;
@@ -295,7 +304,7 @@ char ARMConstantIslands::ID = 0;
/// verify - check BBOffsets, BBSizes, alignment of islands
void ARMConstantIslands::verify() {
#ifndef NDEBUG
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
assert(is_sorted(*MF, [&BBInfo](const MachineBasicBlock &LHS,
const MachineBasicBlock &RHS) {
return BBInfo[LHS.getNumber()].postOffset() <
@@ -323,7 +332,7 @@ void ARMConstantIslands::verify() {
/// print block size and offset information - debugging
LLVM_DUMP_METHOD void ARMConstantIslands::dumpBBs() {
LLVM_DEBUG({
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
for (unsigned J = 0, E = BBInfo.size(); J !=E; ++J) {
const BasicBlockInfo &BBI = BBInfo[J];
dbgs() << format("%08x %bb.%u\t", BBI.Offset, J)
@@ -390,16 +399,16 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
STI = &MF->getSubtarget<ARMSubtarget>();
TII = STI->getInstrInfo();
- isPositionIndependentOrROPI =
- STI->getTargetLowering()->isPositionIndependent() || STI->isROPI();
+ setIsPositionIndependentOrROPI(
+ STI->getTargetLowering()->isPositionIndependent() || STI->isROPI());
AFI = MF->getInfo<ARMFunctionInfo>();
DT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
- isThumb = AFI->isThumbFunction();
- isThumb1 = AFI->isThumb1OnlyFunction();
- isThumb2 = AFI->isThumb2Function();
+ setIsThumb(AFI->isThumbFunction());
+ setIsThumb1(AFI->isThumb1OnlyFunction());
+ setIsThumb2(AFI->isThumb2Function());
- bool GenerateTBB = isThumb2 || (isThumb1 && SynthesizeThumb1TBB);
+ bool GenerateTBB = getIsThumb2() || (getIsThumb1() && SynthesizeThumb1TBB);
// TBB generation code in this constant island pass has not been adapted to
// deal with speculation barriers.
if (STI->hardenSlsRetBr())
@@ -486,11 +495,11 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &mf) {
}
// Shrink 32-bit Thumb2 load and store instructions.
- if (isThumb2 && !STI->prefers32BitThumb())
+ if (getIsThumb2() && !STI->prefers32BitThumb())
MadeChange |= optimizeThumb2Instructions();
// Shrink 32-bit branch instructions.
- if (isThumb && STI->hasV8MBaselineOps())
+ if (getIsThumb() && STI->hasV8MBaselineOps())
MadeChange |= optimizeThumb2Branches();
// Optimize jump tables using TBB / TBH.
@@ -711,9 +720,9 @@ Align ARMConstantIslands::getCPEAlign(const MachineInstr *CPEMI) {
case ARM::CONSTPOOL_ENTRY:
break;
case ARM::JUMPTABLE_TBB:
- return isThumb1 ? Align(4) : Align(1);
+ return getIsThumb1() ? Align(4) : Align(1);
case ARM::JUMPTABLE_TBH:
- return isThumb1 ? Align(4) : Align(2);
+ return getIsThumb1() ? Align(4) : Align(2);
case ARM::JUMPTABLE_INSTS:
return Align(2);
case ARM::JUMPTABLE_ADDRS:
@@ -746,7 +755,7 @@ void ARMConstantIslands::
initializeFunctionInfo(const std::vector<MachineInstr*> &CPEMIs) {
BBUtils->computeAllBlockSizes();
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
// The known bits of the entry block offset are determined by the function
// alignment.
BBInfo.front().KnownBits = Log2(MF->getAlignment());
@@ -982,8 +991,8 @@ MachineBasicBlock *ARMConstantIslands::splitBlockBeforeInstr(MachineInstr *MI) {
// Note the new unconditional branch is not being recorded.
// There doesn't seem to be meaningful DebugInfo available; this doesn't
// correspond to anything in the source.
- unsigned Opc = isThumb ? (isThumb2 ? ARM::t2B : ARM::tB) : ARM::B;
- if (!isThumb)
+ unsigned Opc = getIsThumb() ? (getIsThumb2() ? ARM::t2B : ARM::tB) : ARM::B;
+ if (!getIsThumb())
BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB);
else
BuildMI(OrigBB, DebugLoc(), TII->get(Opc))
@@ -1047,12 +1056,12 @@ MachineBasicBlock *ARMConstantIslands::splitBlockBeforeInstr(MachineInstr *MI) {
unsigned ARMConstantIslands::getUserOffset(CPUser &U) const {
unsigned UserOffset = BBUtils->getOffsetOf(U.MI);
- SmallVectorImpl<BasicBlockInfo> &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
const BasicBlockInfo &BBI = BBInfo[U.MI->getParent()->getNumber()];
unsigned KnownBits = BBI.internalKnownBits();
// The value read from PC is offset from the actual instruction address.
- UserOffset += (isThumb ? 4 : 8);
+ UserOffset += (getIsThumb() ? 4 : 8);
// Because of inline assembly, we may not know the alignment (mod 4) of U.MI.
// Make sure U.getMaxDisp() returns a constrained range.
@@ -1061,7 +1070,7 @@ unsigned ARMConstantIslands::getUserOffset(CPUser &U) const {
// On Thumb, offsets==2 mod 4 are rounded down by the hardware for
// purposes of the displacement computation; compensate for that here.
// For unknown alignments, getMaxDisp() constrains the range instead.
- if (isThumb && U.KnownAlignment)
+ if (getIsThumb() && U.KnownAlignment)
UserOffset &= ~3u;
return UserOffset;
@@ -1096,7 +1105,7 @@ bool ARMConstantIslands::isOffsetInRange(unsigned UserOffset,
bool ARMConstantIslands::isWaterInRange(unsigned UserOffset,
MachineBasicBlock* Water, CPUser &U,
unsigned &Growth) {
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
const Align CPEAlign = getCPEAlign(U.CPEMI);
const unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset(CPEAlign);
unsigned NextBlockOffset;
@@ -1141,7 +1150,7 @@ bool ARMConstantIslands::isCPEntryInRange(MachineInstr *MI, unsigned UserOffset,
if (DoDump) {
LLVM_DEBUG({
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
unsigned Block = MI->getParent()->getNumber();
const BasicBlockInfo &BBI = BBInfo[Block];
dbgs() << "User of CPE#" << CPEMI->getOperand(0).getImm()
@@ -1289,7 +1298,7 @@ bool ARMConstantIslands::findAvailableWater(CPUser &U, unsigned UserOffset,
// When a CP access is out of range, BB0 may be used as water. However,
// inserting islands between BB0 and BB1 makes other accesses out of range.
MachineBasicBlock *UserBB = U.MI->getParent();
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
const Align CPEAlign = getCPEAlign(U.CPEMI);
unsigned MinNoSplitDisp = BBInfo[UserBB->getNumber()].postOffset(CPEAlign);
if (CloserWater && MinNoSplitDisp > U.getMaxDisp() / 2)
@@ -1346,7 +1355,7 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex,
MachineInstr *CPEMI = U.CPEMI;
const Align CPEAlign = getCPEAlign(CPEMI);
MachineBasicBlock *UserMBB = UserMI->getParent();
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
const BasicBlockInfo &UserBBI = BBInfo[UserMBB->getNumber()];
// If the block does not end in an unconditional branch already, and if the
@@ -1355,7 +1364,7 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex,
// Thumb2, 2 on Thumb1.
if (BBHasFallthrough(UserMBB)) {
// Size of branch to insert.
- unsigned Delta = isThumb1 ? 2 : 4;
+ unsigned Delta = getIsThumb1() ? 2 : 4;
// Compute the offset where the CPE will begin.
unsigned CPEOffset = UserBBI.postOffset(CPEAlign) + Delta;
@@ -1368,8 +1377,9 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex,
// but if the preceding conditional branch is out of range, the targets
// will be exchanged, and the altered branch may be out of range, so the
// machinery has to know about it.
- int UncondBr = isThumb ? ((isThumb2) ? ARM::t2B : ARM::tB) : ARM::B;
- if (!isThumb)
+ int UncondBr =
+ getIsThumb() ? ((getIsThumb2()) ? ARM::t2B : ARM::tB) : ARM::B;
+ if (!getIsThumb())
BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB);
else
BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr))
@@ -1499,7 +1509,8 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex,
// the instruction and fail to update the MOVT instruction.
// (These instructions are bundled up until right before the ConstantIslands
// pass.)
- if (STI->isTargetWindows() && isThumb && MI->getOpcode() == ARM::t2MOVTi16 &&
+ if (STI->isTargetWindows() && getIsThumb() &&
+ MI->getOpcode() == ARM::t2MOVTi16 &&
(MI->getOperand(2).getTargetFlags() & ARMII::MO_OPTION_MASK) ==
ARMII::MO_HI16) {
--MI;
@@ -1511,7 +1522,7 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex,
// We really must not split an IT block.
#ifndef NDEBUG
Register PredReg;
- assert(!isThumb || getITInstrPredicate(*MI, PredReg) == ARMCC::AL);
+ assert(!getIsThumb() || getITInstrPredicate(*MI, PredReg) == ARMCC::AL);
#endif
NewMBB = splitBlockBeforeInstr(&*MI);
}
@@ -1577,7 +1588,7 @@ bool ARMConstantIslands::handleConstantPoolUser(unsigned CPUserIndex,
// Always align the new block because CP entries can be smaller than 4
// bytes. Be careful not to decrease the existing alignment, e.g. NewMBB may
// be an already aligned constant pool block.
- const Align Alignment = isThumb ? Align(2) : Align(4);
+ const Align Alignment = getIsThumb() ? Align(2) : Align(4);
if (NewMBB->getAlignment() < Alignment)
NewMBB->setAlignment(Alignment);
@@ -1635,7 +1646,7 @@ void ARMConstantIslands::removeDeadCPEMI(MachineInstr *CPEMI) {
MachineBasicBlock *CPEBB = CPEMI->getParent();
unsigned Size = CPEMI->getOperand(2).getImm();
CPEMI->eraseFromParent();
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
BBUtils->adjustBBSize(CPEBB, -Size);
// All succeeding offsets have the current size value added in, fix this.
if (CPEBB->empty()) {
@@ -1696,7 +1707,7 @@ bool
ARMConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
MachineInstr *MI = Br.MI;
MachineBasicBlock *MBB = MI->getParent();
- if (!isThumb1)
+ if (!getIsThumb1())
llvm_unreachable("fixupUnconditionalBr is Thumb1 only!");
if (!AFI->isLRSpilled())
@@ -1705,7 +1716,7 @@ ARMConstantIslands::fixupUnconditionalBr(ImmBranch &Br) {
// Use BL to implement far jump.
Br.MaxDisp = (1 << 21) * 2;
MI->setDesc(TII->get(ARM::tBfar));
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
BBInfo[MBB->getNumber()].Size += 2;
BBUtils->adjustBBOffsetsAfter(MBB);
++NumUBrFixed;
@@ -1792,7 +1803,7 @@ ARMConstantIslands::fixupConditionalBr(ImmBranch &Br) {
.addMBB(NextBB).addImm(CC).addReg(CCReg);
Br.MI = &MBB->back();
BBUtils->adjustBBSize(MBB, TII->getInstSizeInBytes(MBB->back()));
- if (isThumb)
+ if (getIsThumb())
BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr))
.addMBB(DestBB)
.add(predOps(ARMCC::AL));
@@ -1929,7 +1940,7 @@ bool ARMConstantIslands::optimizeThumb2Branches() {
// Check if the distance is within 126. Subtract starting offset by 2
// because the cmp will be eliminated.
unsigned BrOffset = BBUtils->getOffsetOf(Br.MI) + 4 - 2;
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
unsigned DestOffset = BBInfo[DestBB->getNumber()].Offset;
if (BrOffset >= DestOffset || (DestOffset - BrOffset) > 126)
return false;
@@ -2136,7 +2147,7 @@ bool ARMConstantIslands::preserveBaseRegister(MachineInstr *JumpMI,
if (RemovableAdd) {
RemovableAdd->eraseFromParent();
- DeadSize += isThumb2 ? 4 : 2;
+ DeadSize += getIsThumb2() ? 4 : 2;
} else if (BaseReg == EntryReg) {
// The add wasn't removable, but clobbered the base for the TBB. So we can't
// preserve it.
@@ -2221,7 +2232,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
bool HalfWordOk = true;
unsigned JTOffset = BBUtils->getOffsetOf(MI) + 4;
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
- BBInfoVector &BBInfo = BBUtils->getBBInfo();
+ auto &BBInfo = BBUtils->getBBInfo();
for (MachineBasicBlock *MBB : JTBBs) {
unsigned DstOffset = BBInfo[MBB->getNumber()].Offset;
// Negative offset is not ok. FIXME: We should change BB layout to make
@@ -2249,7 +2260,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
unsigned IdxReg = ~0U;
bool IdxRegKill = true;
- if (isThumb2) {
+ if (getIsThumb2()) {
IdxReg = MI->getOperand(1).getReg();
IdxRegKill = MI->getOperand(1).isKill();
@@ -2302,7 +2313,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
if (registerDefinedBetween(BaseReg, Load->getNextNode(), MBB->end(), TRI))
continue;
- if (isPositionIndependentOrROPI) {
+ if (getIsPositionIndependentOrROPI()) {
MachineInstr *Add = Load->getNextNode();
if (Add->getOpcode() != ARM::tADDrr ||
Add->getOperand(2).getReg() != BaseReg ||
@@ -2334,7 +2345,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
LLVM_DEBUG(dbgs() << "Shrink JT: " << *MI);
MachineInstr *CPEMI = User.CPEMI;
unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;
- if (!isThumb2)
+ if (!getIsThumb2())
Opc = ByteOk ? ARM::tTBB_JT : ARM::tTBH_JT;
MachineBasicBlock::iterator MI_JT = MI;
@@ -2355,11 +2366,11 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
NewJTMI->getOperand(0).setIsKill(false);
if (CanDeleteLEA) {
- if (isThumb2)
+ if (getIsThumb2())
RemoveDeadAddBetweenLEAAndJT(User.MI, MI, DeadSize);
User.MI->eraseFromParent();
- DeadSize += isThumb2 ? 4 : 2;
+ DeadSize += getIsThumb2() ? 4 : 2;
// The LEA was eliminated, the TBB instruction becomes the only new user
// of the jump table.
@@ -2478,7 +2489,7 @@ MachineBasicBlock *ARMConstantIslands::adjustJTTargetBlockForward(
// Add an unconditional branch from NewBB to BB.
// There doesn't seem to be meaningful DebugInfo available; this doesn't
// correspond directly to anything in the source.
- if (isThumb2)
+ if (getIsThumb2())
BuildMI(NewBB, DebugLoc(), TII->get(ARM::t2B))
.addMBB(BB)
.add(predOps(ARMCC::AL));
diff --git a/llvm/lib/Target/ARM/ARMHazardRecognizer.cpp b/llvm/lib/Target/ARM/ARMHazardRecognizer.cpp
index e78f228a912c0..685375251e98f 100644
--- a/llvm/lib/Target/ARM/ARMHazardRecognizer.cpp
+++ b/llvm/lib/Target/ARM/ARMHazardRecognizer.cpp
@@ -164,12 +164,12 @@ static bool getBaseOffset(const MachineInstr &MI, const MachineOperand *&BaseOp,
ARMBankConflictHazardRecognizer::ARMBankConflictHazardRecognizer(
const ScheduleDAG *DAG, int64_t CPUBankMask, bool CPUAssumeITCMConflict)
- : MF(DAG->MF), DL(DAG->MF.getDataLayout()),
+ : Accesses(decltype(this->Accesses)::withFlags(unsigned(bool(
+ AssumeITCMConflict.getNumOccurrences() ? AssumeITCMConflict
+ : CPUAssumeITCMConflict)))),
+ MF(DAG->MF), DL(DAG->MF.getDataLayout()),
DataMask(DataBankMask.getNumOccurrences() ? int64_t(DataBankMask)
- : CPUBankMask),
- AssumeITCMBankConflict(AssumeITCMConflict.getNumOccurrences()
- ? AssumeITCMConflict
- : CPUAssumeITCMConflict) {
+ : CPUBankMask) {
MaxLookAhead = 1;
}
@@ -225,7 +225,7 @@ ARMBankConflictHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
// Constant pools (likely in ITCM)
if (BasePseudoVal0 && BasePseudoVal1 &&
BasePseudoVal0->kind() == BasePseudoVal1->kind() &&
- BasePseudoVal0->isConstantPool() && AssumeITCMBankConflict)
+ BasePseudoVal0->isConstantPool() && getAssumeITCMBankConflict())
return Hazard;
// Is this a stack pointer-relative access? We could in general try to
diff --git a/llvm/lib/Target/ARM/ARMHazardRecognizer.h b/llvm/lib/Target/ARM/ARMHazardRecognizer.h
index b9ac3555c2bc3..99769244ae7c3 100644
--- a/llvm/lib/Target/ARM/ARMHazardRecognizer.h
+++ b/llvm/lib/Target/ARM/ARMHazardRecognizer.h
@@ -16,6 +16,7 @@
#include "ARMBaseInstrInfo.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/Support/DataTypes.h"
#include <initializer_list>
@@ -44,11 +45,12 @@ class ARMHazardRecognizerFPMLx : public ScheduleHazardRecognizer {
// Hazards related to bank conflicts
class ARMBankConflictHazardRecognizer : public ScheduleHazardRecognizer {
- SmallVector<MachineInstr *, 8> Accesses;
+ llvm::SmallVectorWithFlags<MachineInstr *, 8> Accesses;
const MachineFunction &MF;
const DataLayout &DL;
int64_t DataMask;
- bool AssumeITCMBankConflict;
+ bool getAssumeITCMBankConflict() const { return Accesses.getFlag(0); }
+ void setAssumeITCMBankConflict(bool Value) { Accesses.setFlag(0, Value); }
public:
ARMBankConflictHazardRecognizer(const ScheduleDAG *DAG, int64_t DDM,
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index cd038985c2f71..3c0e1bd255fa1 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1796,9 +1796,9 @@ SDValue ARMTargetLowering::MoveFromHPR(const SDLoc &dl, SelectionDAG &DAG,
/// appropriate copies out of appropriate physical registers.
SDValue ARMTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
- SDValue ThisVal, bool isCmseNSCall) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals, bool isThisReturn, SDValue ThisVal,
+ bool isCmseNSCall) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
@@ -2014,15 +2014,14 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &dl = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
- SDValue Callee = CLI.Callee;
- bool &isTailCall = CLI.IsTailCall;
+ SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool doesNotRet = CLI.DoesNotReturn;
- bool isVarArg = CLI.IsVarArg;
+ bool doesNotRet = CLI.getDoesNotReturn();
+ bool isVarArg = CLI.getIsVarArg();
const CallBase *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
@@ -2056,13 +2055,13 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Disable tail calls if they're not supported.
if (!Subtarget->supportsTailCall())
- isTailCall = false;
+ CLI.setIsTailCall(false);
// For both the non-secure calls and the returns from a CMSE entry function,
// the function needs to do some extra work after the call, or before the
// return, respectively, thus it cannot end with a tail call
if (isCmseNSCall || AFI->isCmseNSEntryFunction())
- isTailCall = false;
+ CLI.setIsTailCall(false);
if (isa<GlobalAddressSDNode>(Callee)) {
// If we're optimizing for minimum size and the function is called three or
@@ -2078,22 +2077,23 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
}) > 2;
}
}
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
// Check if it's really possible to do a tail call.
- isTailCall =
- IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs, PreferIndirect);
+ CLI.setIsTailCall(IsEligibleForTailCallOptimization(CLI, CCInfo, ArgLocs,
+ PreferIndirect));
- if (isTailCall && !getTargetMachine().Options.GuaranteedTailCallOpt &&
+ if (CLI.getIsTailCall() &&
+ !getTargetMachine().Options.GuaranteedTailCallOpt &&
CallConv != CallingConv::Tail && CallConv != CallingConv::SwiftTail)
isSibCall = true;
// We don't support GuaranteedTailCallOpt for ARM, only automatically
// detected sibcalls.
- if (isTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
}
- if (!isTailCall && CLI.CB && CLI.CB->isMustTailCall())
+ if (!CLI.getIsTailCall() && CLI.CB && CLI.CB->isMustTailCall())
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail");
@@ -2107,7 +2107,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// arguments to begin at SP+0. Completely unused for non-tail calls.
int SPDiff = 0;
- if (isTailCall && !isSibCall) {
+ if (CLI.getIsTailCall() && !isSibCall) {
auto FuncInfo = MF.getInfo<ARMFunctionInfo>();
unsigned NumReusableBytes = FuncInfo->getArgumentStackSize();
@@ -2134,7 +2134,8 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
} else {
// Adjust the stack pointer for the new arguments...
// These operations are automatically eliminated by the prolog/epilog pass
- Chain = DAG.getCALLSEQ_START(Chain, isTailCall ? 0 : NumBytes, 0, dl);
+ Chain =
+ DAG.getCALLSEQ_START(Chain, CLI.getIsTailCall() ? 0 : NumBytes, 0, dl);
}
SDValue StackPtr =
@@ -2151,7 +2152,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// to the argument area.
DenseMap<unsigned, SDValue> ByValTemporaries;
SDValue ByValTempChain;
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
SmallVector<SDValue, 8> ByValCopyChains;
for (const CCValAssign &VA : ArgLocs) {
unsigned ArgIdx = VA.getValNo();
@@ -2238,7 +2239,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
break;
}
- if (isTailCall && VA.isMemLoc() && !AfterFormalArgLoads) {
+ if (CLI.getIsTailCall() && VA.isMemLoc() && !AfterFormalArgLoads) {
Chain = DAG.getStackArgumentTokenFactor(Chain);
if (ByValTempChain) {
// In case of large byval copies, re-using the stackframe for tail-calls
@@ -2310,23 +2311,23 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
DAG.getConstant(1, dl, MVT::i32));
PassF64ArgInRegs(dl, DAG, Chain, Op0, RegsToPass, VA, ArgLocs[++i],
- StackPtr, MemOpChains, isTailCall, SPDiff);
+ StackPtr, MemOpChains, CLI.getIsTailCall(), SPDiff);
VA = ArgLocs[++i]; // skip ahead to next loc
if (VA.isRegLoc()) {
PassF64ArgInRegs(dl, DAG, Chain, Op1, RegsToPass, VA, ArgLocs[++i],
- StackPtr, MemOpChains, isTailCall, SPDiff);
+ StackPtr, MemOpChains, CLI.getIsTailCall(), SPDiff);
} else {
assert(VA.isMemLoc());
SDValue DstAddr;
MachinePointerInfo DstInfo;
- std::tie(DstAddr, DstInfo) =
- computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
+ std::tie(DstAddr, DstInfo) = computeAddrForCallArg(
+ dl, DAG, VA, StackPtr, CLI.getIsTailCall(), SPDiff);
MemOpChains.push_back(DAG.getStore(Chain, dl, Op1, DstAddr, DstInfo));
}
} else if (VA.needsCustom() && VA.getLocVT() == MVT::f64) {
PassF64ArgInRegs(dl, DAG, Chain, Arg, RegsToPass, VA, ArgLocs[++i],
- StackPtr, MemOpChains, isTailCall, SPDiff);
+ StackPtr, MemOpChains, CLI.getIsTailCall(), SPDiff);
} else if (VA.isRegLoc()) {
if (realArgIdx == 0 && Flags.isReturned() && !Flags.isSwiftSelf() &&
Outs[0].VT == MVT::i32) {
@@ -2357,7 +2358,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
NeedsStackCopy = true;
} else {
ByValSrc = Arg;
- NeedsStackCopy = !isTailCall;
+ NeedsStackCopy = !CLI.getIsTailCall();
}
// If part of the argument is in registers, load them.
@@ -2390,8 +2391,8 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
auto PtrVT = getPointerTy(DAG.getDataLayout());
SDValue Dst;
MachinePointerInfo DstInfo;
- std::tie(Dst, DstInfo) =
- computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
+ std::tie(Dst, DstInfo) = computeAddrForCallArg(
+ dl, DAG, VA, StackPtr, CLI.getIsTailCall(), SPDiff);
SDValue SrcOffset = DAG.getIntPtrConstant(4*offset, dl);
SDValue Src = DAG.getNode(ISD::ADD, dl, PtrVT, ByValSrc, SrcOffset);
SDValue SizeNode = DAG.getConstant(Flags.getByValSize() - 4*offset, dl,
@@ -2408,8 +2409,8 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
assert(VA.isMemLoc());
SDValue DstAddr;
MachinePointerInfo DstInfo;
- std::tie(DstAddr, DstInfo) =
- computeAddrForCallArg(dl, DAG, VA, StackPtr, isTailCall, SPDiff);
+ std::tie(DstAddr, DstInfo) = computeAddrForCallArg(
+ dl, DAG, VA, StackPtr, CLI.getIsTailCall(), SPDiff);
SDValue Store = DAG.getStore(Chain, dl, Arg, DstAddr, DstInfo);
MemOpChains.push_back(Store);
@@ -2631,7 +2632,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// the frame up *after* the call, however in the ABI-changing tail-call case
// we've carefully laid out the parameters so that when sp is reset they'll be
// in the correct location.
- if (isTailCall && !isSibCall) {
+ if (CLI.getIsTailCall() && !isSibCall) {
Chain = DAG.getCALLSEQ_END(Chain, 0, 0, InGlue, dl);
InGlue = Chain.getValue(1);
}
@@ -2640,7 +2641,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Ops.push_back(Chain);
Ops.push_back(Callee);
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
Ops.push_back(DAG.getSignedTargetConstant(SPDiff, dl, MVT::i32));
}
@@ -2671,12 +2672,12 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (InGlue.getNode())
Ops.push_back(InGlue);
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
MF.getFrameInfo().setHasTailCall();
SDValue Ret = DAG.getNode(ARMISD::TC_RETURN, dl, MVT::Other, Ops);
if (CLI.CFIType)
Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
- DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.getNoMerge());
DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
return Ret;
}
@@ -2685,7 +2686,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Chain = DAG.getNode(CallOpc, dl, {MVT::Other, MVT::Glue}, Ops);
if (CLI.CFIType)
Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.getNoMerge());
InGlue = Chain.getValue(1);
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
@@ -2771,10 +2772,10 @@ bool ARMTargetLowering::IsEligibleForTailCallOptimization(
SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const {
CallingConv::ID CalleeCC = CLI.CallConv;
SDValue Callee = CLI.Callee;
- bool isVarArg = CLI.IsVarArg;
- const SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ bool isVarArg = CLI.getIsVarArg();
+ const auto &Outs = CLI.Outs;
const SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- const SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ const auto &Ins = CLI.Ins;
const SelectionDAG &DAG = CLI.DAG;
MachineFunction &MF = DAG.getMachineFunction();
const Function &CallerF = MF.getFunction();
@@ -2877,7 +2878,7 @@ bool ARMTargetLowering::IsEligibleForTailCallOptimization(
// not perform tail call, since part of the argument is in caller's local
// frame.
const ARMFunctionInfo *AFI_Caller = MF.getInfo<ARMFunctionInfo>();
- if (CLI.IsVarArg && AFI_Caller->getArgRegsSaveSize()) {
+ if (CLI.getIsVarArg() && AFI_Caller->getArgRegsSaveSize()) {
LLVM_DEBUG(dbgs() << "false (arg reg save area)\n");
return false;
}
@@ -2899,11 +2900,11 @@ bool ARMTargetLowering::IsEligibleForTailCallOptimization(
return true;
}
-bool
-ARMTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
- MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- LLVMContext &Context, const Type *RetTy) const {
+bool ARMTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg));
@@ -2942,12 +2943,12 @@ static SDValue LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
return DAG.getNode(ARMISD::INTRET_GLUE, DL, MVT::Other, RetOps);
}
-SDValue
-ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &dl, SelectionDAG &DAG) const {
+SDValue ARMTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &dl,
+ SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of the return value to a location.
SmallVector<CCValAssign, 16> RVLocs;
@@ -4251,8 +4252,8 @@ SDValue ARMTargetLowering::joinRegisterPartsIntoValue(
SDValue ARMTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index 4f95a1cdeb2ef..0288508ea8d9c 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -637,10 +637,10 @@ class VectorType;
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
- SDValue ThisVal, bool isCmseNSCall) const;
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
+ bool isThisReturn, SDValue ThisVal,
+ bool isCmseNSCall) const;
void initializeSplitCSR(MachineBasicBlock *Entry) const override;
void insertCopiesSplitCSR(
@@ -659,8 +659,8 @@ class VectorType;
SDValue
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
int StoreByValRegs(CCState &CCInfo, SelectionDAG &DAG, const SDLoc &dl,
@@ -686,13 +686,12 @@ class VectorType;
TargetLowering::CallLoweringInfo &CLI, CCState &CCInfo,
SmallVectorImpl<CCValAssign> &ArgLocs, const bool isIndirect) const;
- bool CanLowerReturn(CallingConv::ID CallConv,
- MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 1dd0087cf81eb..9f495306572e2 100644
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -108,8 +109,15 @@ struct ARMLoadStoreOpt {
LiveRegUnits LiveRegs;
const RegisterClassInfo *RCI = nullptr;
MachineBasicBlock::const_iterator LiveRegPos;
- bool LiveRegsValid;
- bool isThumb1, isThumb2;
+ bool getLiveRegsValid() const { return MergeBaseCandidates.getFlag(0); }
+ bool setLiveRegsValid(bool Value) {
+ MergeBaseCandidates.setFlag(0, Value);
+ return Value;
+ }
+ bool getIsThumb1() const { return MergeBaseCandidates.getFlag(1); }
+ void setIsThumb1(bool Value) { MergeBaseCandidates.setFlag(1, Value); }
+ bool getIsThumb2() const { return MergeBaseCandidates.getFlag(2); }
+ void setIsThumb2(bool Value) { MergeBaseCandidates.setFlag(2, Value); }
bool runOnMachineFunction(MachineFunction &Fn,
const RegisterClassInfo &RegClassInfo);
@@ -151,7 +159,7 @@ struct ARMLoadStoreOpt {
};
SpecificBumpPtrAllocator<MergeCandidate> Allocator;
SmallVector<const MergeCandidate *, 4> Candidates;
- SmallVector<MachineInstr *, 4> MergeBaseCandidates;
+ llvm::SmallVectorWithFlags<MachineInstr *, 4, 3> MergeBaseCandidates;
MachineBasicBlock::iterator eraseInstr(MachineBasicBlock::iterator MI);
@@ -502,7 +510,7 @@ void ARMLoadStoreOpt::UpdateBaseRegUses(MachineBasicBlock &MBB,
unsigned WordOffset,
ARMCC::CondCodes Pred,
unsigned PredReg) {
- assert(isThumb1 && "Can only update base register uses for Thumb1!");
+ assert(getIsThumb1() && "Can only update base register uses for Thumb1!");
// Start updating any instructions with immediate offsets. Insert a SUB before
// the first non-updateable instruction (if any).
for (; MBBI != MBB.end(); ++MBBI) {
@@ -598,8 +606,8 @@ void ARMLoadStoreOpt::UpdateBaseRegUses(MachineBasicBlock &MBB,
MachineBasicBlock::iterator
ARMLoadStoreOpt::eraseInstr(MachineBasicBlock::iterator MI) {
- if (LiveRegsValid && LiveRegPos == MI)
- LiveRegsValid = false;
+ if (getLiveRegsValid() && LiveRegPos == MI)
+ setLiveRegsValid(false);
return MI->eraseFromParent();
}
@@ -617,11 +625,11 @@ unsigned ARMLoadStoreOpt::findFreeReg(const TargetRegisterClass &RegClass) {
void ARMLoadStoreOpt::moveLiveRegsBefore(const MachineBasicBlock &MBB,
MachineBasicBlock::const_iterator Before) {
// Initialize if we never queried in this block.
- if (!LiveRegsValid) {
+ if (!getLiveRegsValid()) {
LiveRegs.init(*TRI);
LiveRegs.addLiveOuts(MBB);
LiveRegPos = MBB.end();
- LiveRegsValid = true;
+ setLiveRegsValid(true);
}
// Move backward just before the "Before" position.
while (LiveRegPos != Before) {
@@ -653,16 +661,17 @@ MachineInstr *ARMLoadStoreOpt::CreateLoadStoreMulti(
// For Thumb1 targets, it might be necessary to clobber the CPSR to merge.
// Compute liveness information for that register to make the decision.
- bool SafeToClobberCPSR = !isThumb1 ||
- (MBB.computeRegisterLiveness(TRI, ARM::CPSR, InsertBefore, 20) ==
- MachineBasicBlock::LQR_Dead);
+ bool SafeToClobberCPSR =
+ !getIsThumb1() ||
+ (MBB.computeRegisterLiveness(TRI, ARM::CPSR, InsertBefore, 20) ==
+ MachineBasicBlock::LQR_Dead);
- bool Writeback = isThumb1; // Thumb1 LDM/STM have base reg writeback.
+ bool Writeback = getIsThumb1(); // Thumb1 LDM/STM have base reg writeback.
// Exception: If the base register is in the input reglist, Thumb1 LDM is
// non-writeback.
// It's also not possible to merge an STR of the base register in Thumb1.
- if (isThumb1 && ContainsReg(Regs, Base)) {
+ if (getIsThumb1() && ContainsReg(Regs, Base)) {
assert(Base != ARM::SP && "Thumb1 does not allow SP in register list");
if (Opcode == ARM::tLDRi)
Writeback = false;
@@ -673,13 +682,13 @@ MachineInstr *ARMLoadStoreOpt::CreateLoadStoreMulti(
ARM_AM::AMSubMode Mode = ARM_AM::ia;
// VFP and Thumb2 do not support IB or DA modes. Thumb1 only supports IA.
bool isNotVFP = isi32Load(Opcode) || isi32Store(Opcode);
- bool haveIBAndDA = isNotVFP && !isThumb2 && !isThumb1;
+ bool haveIBAndDA = isNotVFP && !getIsThumb2() && !getIsThumb1();
if (Offset == 4 && haveIBAndDA) {
Mode = ARM_AM::ib;
} else if (Offset == -4 * (int)NumRegs + 4 && haveIBAndDA) {
Mode = ARM_AM::da;
- } else if (Offset == -4 * (int)NumRegs && isNotVFP && !isThumb1) {
+ } else if (Offset == -4 * (int)NumRegs && isNotVFP && !getIsThumb1()) {
// VLDM/VSTM do not support DB mode without also updating the base reg.
Mode = ARM_AM::db;
} else if (Offset != 0 || Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi) {
@@ -713,28 +722,28 @@ MachineInstr *ARMLoadStoreOpt::CreateLoadStoreMulti(
for (const std::pair<unsigned, bool> &R : Regs)
LiveRegs.addReg(R.first);
- NewBase = findFreeReg(isThumb1 ? ARM::tGPRRegClass : ARM::GPRRegClass);
+ NewBase =
+ findFreeReg(getIsThumb1() ? ARM::tGPRRegClass : ARM::GPRRegClass);
if (NewBase == 0)
return nullptr;
}
- int BaseOpc = isThumb2 ? (BaseKill && Base == ARM::SP ? ARM::t2ADDspImm
- : ARM::t2ADDri)
- : (isThumb1 && Base == ARM::SP)
- ? ARM::tADDrSPi
- : (isThumb1 && Offset < 8)
- ? ARM::tADDi3
- : isThumb1 ? ARM::tADDi8 : ARM::ADDri;
+ int BaseOpc = getIsThumb2() ? (BaseKill && Base == ARM::SP ? ARM::t2ADDspImm
+ : ARM::t2ADDri)
+ : (getIsThumb1() && Base == ARM::SP) ? ARM::tADDrSPi
+ : (getIsThumb1() && Offset < 8) ? ARM::tADDi3
+ : getIsThumb1() ? ARM::tADDi8
+ : ARM::ADDri;
if (Offset < 0) {
// FIXME: There are no Thumb1 load/store instructions with negative
// offsets. So the Base != ARM::SP might be unnecessary.
Offset = -Offset;
- BaseOpc = isThumb2 ? (BaseKill && Base == ARM::SP ? ARM::t2SUBspImm
- : ARM::t2SUBri)
- : (isThumb1 && Offset < 8 && Base != ARM::SP)
- ? ARM::tSUBi3
- : isThumb1 ? ARM::tSUBi8 : ARM::SUBri;
+ BaseOpc = getIsThumb2() ? (BaseKill && Base == ARM::SP ? ARM::t2SUBspImm
+ : ARM::t2SUBri)
+ : (getIsThumb1() && Offset < 8 && Base != ARM::SP) ? ARM::tSUBi3
+ : getIsThumb1() ? ARM::tSUBi8
+ : ARM::SUBri;
}
if (!TL->isLegalAddImmediate(Offset))
@@ -746,7 +755,7 @@ MachineInstr *ARMLoadStoreOpt::CreateLoadStoreMulti(
bool KillOldBase = BaseKill &&
(!isi32Store(Opcode) || !ContainsReg(Regs, Base));
- if (isThumb1) {
+ if (getIsThumb1()) {
// Thumb1: depending on immediate size, use either
// ADDS NewBase, Base, #imm3
// or
@@ -810,13 +819,13 @@ MachineInstr *ARMLoadStoreOpt::CreateLoadStoreMulti(
// Otherwise, don't merge.
// It's safe to return here since the code to materialize a new base register
// above is also conditional on SafeToClobberCPSR.
- if (isThumb1 && !SafeToClobberCPSR && Writeback && !BaseKill)
+ if (getIsThumb1() && !SafeToClobberCPSR && Writeback && !BaseKill)
return nullptr;
MachineInstrBuilder MIB;
if (Writeback) {
- assert(isThumb1 && "expected Writeback only inThumb1");
+ assert(getIsThumb1() && "expected Writeback only inThumb1");
if (Opcode == ARM::tLDMIA) {
assert(!(ContainsReg(Regs, Base)) && "Thumb1 can't LDM ! with Base in Regs");
// Update tLDMIA with writeback if necessary.
@@ -1305,7 +1314,8 @@ findIncDecAfter(MachineBasicBlock::iterator MBBI, Register Reg,
/// ldmdb rn!, <ra, rb, rc>
bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineInstr *MI) {
// Thumb1 is already using updating loads/stores.
- if (isThumb1) return false;
+ if (getIsThumb1())
+ return false;
LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << *MI);
const MachineOperand &BaseOP = MI->getOperand(0);
@@ -1486,7 +1496,8 @@ static unsigned getPostIndexedLoadStoreOpcode(unsigned Opc,
bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineInstr *MI) {
// Thumb1 doesn't have updating LDR/STR.
// FIXME: Use LDM/STM with single register instead.
- if (isThumb1) return false;
+ if (getIsThumb1())
+ return false;
LLVM_DEBUG(dbgs() << "Attempting to merge update of: " << *MI);
Register Base = getLoadStoreBaseOp(*MI).getReg();
@@ -1902,7 +1913,7 @@ bool ARMLoadStoreOpt::LoadStoreMultipleOpti(MachineBasicBlock &MBB) {
unsigned Position = 0;
assert(Candidates.size() == 0);
assert(MergeBaseCandidates.size() == 0);
- LiveRegsValid = false;
+ setLiveRegsValid(false);
for (MachineBasicBlock::iterator I = MBB.end(), MBBI; I != MBB.begin();
I = MBBI) {
@@ -2055,7 +2066,8 @@ bool ARMLoadStoreOpt::LoadStoreMultipleOpti(MachineBasicBlock &MBB) {
/// ldmfd sp!, {..., pc}
bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
// Thumb1 LDM doesn't allow high registers.
- if (isThumb1) return false;
+ if (getIsThumb1())
+ return false;
if (MBB.empty()) return false;
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
@@ -2075,9 +2087,10 @@ bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
MachineOperand &MO = PrevMI.getOperand(PrevMI.getNumOperands() - 1);
if (MO.getReg() != ARM::LR)
return false;
- unsigned NewOpc = (isThumb2 ? ARM::t2LDMIA_RET : ARM::LDMIA_RET);
- assert(((isThumb2 && Opcode == ARM::t2LDMIA_UPD) ||
- Opcode == ARM::LDMIA_UPD) && "Unsupported multiple load-return!");
+ unsigned NewOpc = (getIsThumb2() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET);
+ assert(((getIsThumb2() && Opcode == ARM::t2LDMIA_UPD) ||
+ Opcode == ARM::LDMIA_UPD) &&
+ "Unsupported multiple load-return!");
PrevMI.setDesc(TII->get(NewOpc));
MO.setReg(ARM::PC);
PrevMI.copyImplicitOps(*MBB.getParent(), *MBBI);
@@ -2125,15 +2138,15 @@ bool ARMLoadStoreOpt::runOnMachineFunction(
TRI = STI->getRegisterInfo();
RCI = &RegClassInfo;
- isThumb2 = AFI->isThumb2Function();
- isThumb1 = AFI->isThumbFunction() && !isThumb2;
+ setIsThumb2(AFI->isThumb2Function());
+ setIsThumb1(AFI->isThumbFunction() && !getIsThumb2());
bool Modified = false, ModifiedLDMReturn = false;
for (MachineBasicBlock &MBB : Fn) {
Modified |= LoadStoreMultipleOpti(MBB);
if (STI->hasV5TOps() && !AFI->shouldSignReturnAddress())
ModifiedLDMReturn |= MergeReturnIntoLDM(MBB);
- if (isThumb1)
+ if (getIsThumb1())
Modified |= CombineMovBx(MBB);
}
Modified |= ModifiedLDMReturn;
diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
index 3635fb3da020c..8230c162805e8 100644
--- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
+++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
@@ -58,6 +58,7 @@
#include "MVETailPredUtils.h"
#include "Thumb2InstrInfo.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -373,13 +374,15 @@ namespace {
MachineInstr *Dec = nullptr;
MachineInstr *End = nullptr;
MachineOperand TPNumElements;
- SmallVector<MachineInstr *, 4> VCTPs;
+ llvm::SmallVectorWithFlags<MachineInstr *, 4, 2> VCTPs;
SmallPtrSet<MachineInstr *, 4> ToRemove;
SmallPtrSet<MachineInstr *, 4> BlockMasksToRecompute;
SmallPtrSet<MachineInstr *, 4> DoubleWidthResultInstrs;
SmallPtrSet<MachineInstr *, 4> VMOVCopies;
- bool Revert = false;
- bool CannotTailPredicate = false;
+ bool getRevert() const { return VCTPs.getFlag(0); }
+ void setRevert(bool Value) { VCTPs.setFlag(0, Value); }
+ bool getCannotTailPredicate() const { return VCTPs.getFlag(1); }
+ void setCannotTailPredicate(bool Value) { VCTPs.setFlag(1, Value); }
VPTState VPTstate;
LowOverheadLoop(MachineLoop &ML, MachineLoopInfo &MLI, ReachingDefInfo &RDI,
@@ -399,14 +402,14 @@ namespace {
bool ValidateMVEInst(MachineInstr *MI);
void AnalyseMVEInst(MachineInstr *MI) {
- CannotTailPredicate = !ValidateMVEInst(MI);
+ setCannotTailPredicate(!ValidateMVEInst(MI));
}
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() &&
- !CannotTailPredicate && ML.getNumBlocks() == 1;
+ return !getRevert() && FoundAllComponents() && !VCTPs.empty() &&
+ !getCannotTailPredicate() && ML.getNumBlocks() == 1;
}
// Given that MI is a VCTP, check that is equivalent to any other VCTPs
@@ -1067,7 +1070,7 @@ bool LowOverheadLoop::ValidateLiveOuts() {
}
void LowOverheadLoop::Validate(ARMBasicBlockUtils *BBUtils) {
- if (Revert)
+ if (getRevert())
return;
// Check branch target ranges: WLS[TP] can only branch forwards and LE[TP]
@@ -1108,8 +1111,8 @@ void LowOverheadLoop::Validate(ARMBasicBlockUtils *BBUtils) {
LLVM_DEBUG(dbgs() << "ARM Loops: Will insert LoopStart at "
<< *StartInsertPt);
- Revert = !ValidateRanges(Start, End, BBUtils, ML);
- CannotTailPredicate = !ValidateTailPredicate();
+ setRevert(!ValidateRanges(Start, End, BBUtils, ML));
+ setCannotTailPredicate(!ValidateTailPredicate());
}
bool LowOverheadLoop::AddVCTP(MachineInstr *MI) {
@@ -1211,7 +1214,7 @@ static bool ValidateMVEStore(MachineInstr *MI, MachineLoop *ML) {
}
bool LowOverheadLoop::ValidateMVEInst(MachineInstr *MI) {
- if (CannotTailPredicate)
+ if (getCannotTailPredicate())
return false;
if (!shouldInspect(*MI))
@@ -1380,7 +1383,7 @@ bool ARMLowOverheadLoops::ProcessLoop(MachineLoop *ML) {
// TODO: Though the call will require LE to execute again, does this
// mean we should revert? Always executing LE hopefully should be
// faster than performing a sub,cmp,br or even subs,br.
- LoLoop.Revert = true;
+ LoLoop.setRevert(true);
LLVM_DEBUG(dbgs() << "ARM Loops: Found call.\n");
} else {
// Record VPR defs and build up their corresponding vpt blocks.
@@ -1407,7 +1410,7 @@ bool ARMLowOverheadLoops::ProcessLoop(MachineLoop *ML) {
RDI->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.setRevert(true);
}
}
LoLoop.Validate(BBUtils.get());
@@ -1769,7 +1772,7 @@ void ARMLowOverheadLoops::Expand(LowOverheadLoop &LoLoop) {
}
};
- if (LoLoop.Revert) {
+ if (LoLoop.getRevert()) {
if (isWhileLoopStart(*LoLoop.Start))
RevertWhile(LoLoop.Start);
else
diff --git a/llvm/lib/Target/ARM/ARMParallelDSP.cpp b/llvm/lib/Target/ARM/ARMParallelDSP.cpp
index 13a52416caab3..4650054faa05f 100644
--- a/llvm/lib/Target/ARM/ARMParallelDSP.cpp
+++ b/llvm/lib/Target/ARM/ARMParallelDSP.cpp
@@ -17,6 +17,7 @@
#include "ARM.h"
#include "ARMSubtarget.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
@@ -64,9 +65,15 @@ namespace {
Instruction *Root;
Value* LHS;
Value* RHS;
- bool Exchange = false;
- bool Paired = false;
- SmallVector<LoadInst*, 2> VecLd; // Container for loads to widen.
+ bool getExchange() const { return VecLd.getFlag(0); }
+ bool setExchange(bool Value) {
+ VecLd.setFlag(0, Value);
+ return Value;
+ }
+ bool getPaired() const { return VecLd.getFlag(1); }
+ void setPaired(bool Value) { VecLd.setFlag(1, Value); }
+ llvm::SmallVectorWithFlags<LoadInst *, 2, 2>
+ VecLd; // Container for loads to widen.
MulCandidate(Instruction *I, Value *lhs, Value *rhs) :
Root(I), LHS(lhs), RHS(rhs) { }
@@ -145,10 +152,10 @@ namespace {
LLVM_DEBUG(dbgs() << "Pairing:\n"
<< *Mul0->Root << "\n"
<< *Mul1->Root << "\n");
- Mul0->Paired = true;
- Mul1->Paired = true;
+ Mul0->setPaired(true);
+ Mul1->setPaired(true);
if (Exchange)
- Mul1->Exchange = true;
+ Mul1->setExchange(true);
MulPairs.push_back(std::make_pair(Mul0, Mul1));
}
@@ -196,8 +203,7 @@ namespace {
SmallVector<LoadInst*, 4> Loads;
public:
- WidenedLoad(SmallVectorImpl<LoadInst*> &Lds, LoadInst *Wide)
- : NewLd(Wide) {
+ WidenedLoad(ArrayRef<LoadInst *> Lds, LoadInst *Wide) : NewLd(Wide) {
append_range(Loads, Lds);
}
LoadInst *getLoad() {
@@ -221,8 +227,9 @@ namespace {
bool Search(Value *V, BasicBlock *BB, Reduction &R);
bool RecordMemoryOps(BasicBlock *BB);
void InsertParallelMACs(Reduction &Reduction);
- bool AreSequentialLoads(LoadInst *Ld0, LoadInst *Ld1, MemInstList &VecMem);
- LoadInst* CreateWideLoad(MemInstList &Loads, IntegerType *LoadTy);
+ template <typename LoadVectorT>
+ bool AreSequentialLoads(LoadInst *Ld0, LoadInst *Ld1, LoadVectorT &VecMem);
+ LoadInst *CreateWideLoad(ArrayRef<LoadInst *> Loads, IntegerType *LoadTy);
bool CreateParallelPairs(Reduction &R);
/// Try to match and generate: SMLAD, SMLADX - Signed Multiply Accumulate
@@ -294,8 +301,9 @@ namespace {
};
}
+template <typename LoadVectorT>
bool ARMParallelDSP::AreSequentialLoads(LoadInst *Ld0, LoadInst *Ld1,
- MemInstList &VecMem) {
+ LoadVectorT &VecMem) {
if (!Ld0 || !Ld1)
return false;
@@ -594,7 +602,7 @@ bool ARMParallelDSP::CreateParallelPairs(Reduction &R) {
const unsigned Elems = Muls.size();
for (unsigned i = 0; i < Elems; ++i) {
MulCandidate *PMul0 = static_cast<MulCandidate*>(Muls[i].get());
- if (PMul0->Paired)
+ if (PMul0->getPaired())
continue;
for (unsigned j = 0; j < Elems; ++j) {
@@ -602,7 +610,7 @@ bool ARMParallelDSP::CreateParallelPairs(Reduction &R) {
continue;
MulCandidate *PMul1 = static_cast<MulCandidate*>(Muls[j].get());
- if (PMul1->Paired)
+ if (PMul1->getPaired())
continue;
const Instruction *Mul0 = PMul0->Root;
@@ -667,7 +675,7 @@ void ARMParallelDSP::InsertParallelMACs(Reduction &R) {
IRBuilder<NoFolder> Builder(R.getRoot()->getParent());
MulCandList &MulCands = R.getMuls();
for (auto &MulCand : MulCands) {
- if (MulCand->Paired)
+ if (MulCand->getPaired())
continue;
Instruction *Mul = cast<Instruction>(MulCand->Root);
@@ -724,12 +732,13 @@ void ARMParallelDSP::InsertParallelMACs(Reduction &R) {
Instruction *InsertAfter = GetInsertPoint(WideLHS, WideRHS);
InsertAfter = GetInsertPoint(InsertAfter, Acc);
- Acc = CreateSMLAD(WideLHS, WideRHS, Acc, RHSMul->Exchange, InsertAfter);
+ Acc =
+ CreateSMLAD(WideLHS, WideRHS, Acc, RHSMul->getExchange(), InsertAfter);
}
R.UpdateRoot(cast<Instruction>(Acc));
}
-LoadInst* ARMParallelDSP::CreateWideLoad(MemInstList &Loads,
+LoadInst *ARMParallelDSP::CreateWideLoad(ArrayRef<LoadInst *> Loads,
IntegerType *LoadTy) {
assert(Loads.size() == 2 && "currently only support widening two loads");
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index ab94d8eb21f44..71ec9b955d806 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
@@ -247,7 +248,12 @@ class ARMAsmParser : public MCTargetAsmParser {
// Map of register aliases registers via the .req directive.
StringMap<MCRegister> RegisterReqs;
- bool NextSymbolIsThumb;
+ bool getNextSymbolIsThumb() const {
+ return PendingConditionalInsts.getFlag(0);
+ }
+ void setNextSymbolIsThumb(bool Value) {
+ PendingConditionalInsts.setFlag(0, Value);
+ }
bool useImplicitITThumb() const {
return ImplicitItMode == ImplicitItModeTy::Always ||
@@ -284,7 +290,7 @@ class ARMAsmParser : public MCTargetAsmParser {
// would be legal.
} ITState;
- SmallVector<MCInst, 4> PendingConditionalInsts;
+ llvm::SmallVectorWithFlags<MCInst, 4> PendingConditionalInsts;
void onEndOfFile() override {
flushPendingInstructions(getParser().getStreamer());
@@ -707,7 +713,7 @@ class ARMAsmParser : public MCTargetAsmParser {
VPTState.CurPosition = ~0U;
- NextSymbolIsThumb = false;
+ setNextSymbolIsThumb(false);
}
// Implementation of the MCTargetAsmParser interface:
@@ -11673,9 +11679,9 @@ void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
}
void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
- if (NextSymbolIsThumb) {
+ if (getNextSymbolIsThumb()) {
getTargetStreamer().emitThumbFunc(Symbol);
- NextSymbolIsThumb = false;
+ setNextSymbolIsThumb(false);
}
}
@@ -11711,7 +11717,7 @@ bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
getTargetStreamer().emitCode16();
- NextSymbolIsThumb = true;
+ setNextSymbolIsThumb(true);
return false;
}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index f51a8fd890f3e..b3da381258424 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -481,7 +482,8 @@ class ARMELFStreamer : public MCELFStreamer {
bool IsAndroid)
: MCELFStreamer(Context, std::move(TAB), std::move(OW),
std::move(Emitter)),
- IsThumb(IsThumb), IsAndroid(IsAndroid) {
+ Opcodes(decltype(this->Opcodes)::withFlags(
+ unsigned(IsThumb) | (unsigned(IsAndroid) << 1))) {
EHReset();
}
@@ -521,7 +523,7 @@ class ARMELFStreamer : public MCELFStreamer {
/// necessary.
void emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) override {
- if (IsThumb)
+ if (getIsThumbFlag())
EmitThumbMappingSymbol();
else
EmitARMMappingSymbol();
@@ -538,7 +540,7 @@ class ARMELFStreamer : public MCELFStreamer {
case '\0':
Size = 4;
- assert(!IsThumb);
+ assert(!getIsThumbFlag());
EmitARMMappingSymbol();
for (unsigned II = 0, IE = Size; II != IE; II++) {
const unsigned I = LittleEndian ? (Size - II - 1) : II;
@@ -550,7 +552,7 @@ class ARMELFStreamer : public MCELFStreamer {
case 'w':
Size = (Suffix == 'n' ? 2 : 4);
- assert(IsThumb);
+ assert(getIsThumbFlag());
EmitThumbMappingSymbol();
// Thumb wide instructions are emitted as a pair of 16-bit words of the
// appropriate endianness.
@@ -627,7 +629,7 @@ class ARMELFStreamer : public MCELFStreamer {
return Val;
};
- void setIsThumb(bool Val) { IsThumb = Val; }
+ void setIsThumb(bool Val) { setIsThumbFlag(Val); }
private:
enum ElfMappingSymbol {
@@ -715,8 +717,10 @@ class ARMELFStreamer : public MCELFStreamer {
void SwitchToExTabSection(const MCSymbol &FnStart);
void SwitchToExIdxSection(const MCSymbol &FnStart);
- bool IsThumb;
- bool IsAndroid;
+ bool getIsThumbFlag() const { return Opcodes.getFlag(0); }
+ void setIsThumbFlag(bool Value) { Opcodes.setFlag(0, Value); }
+ bool getIsAndroid() const { return Opcodes.getFlag(1); }
+ void setIsAndroid(bool Value) { Opcodes.setFlag(1, Value); }
DenseSet<const MCSymbol *> ThumbLabels;
DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
@@ -733,9 +737,11 @@ class ARMELFStreamer : public MCELFStreamer {
int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
- bool UsedFP;
- bool CantUnwind;
- SmallVector<uint8_t, 64> Opcodes;
+ bool getUsedFP() const { return Opcodes.getFlag(2); }
+ void setUsedFP(bool Value) { Opcodes.setFlag(2, Value); }
+ bool getCantUnwind() const { return Opcodes.getFlag(3); }
+ void setCantUnwind(bool Value) { Opcodes.setFlag(3, Value); }
+ llvm::SmallVectorWithFlags<uint8_t, 64, 4> Opcodes;
UnwindOpcodeAssembler UnwindOpAsm;
};
@@ -1094,7 +1100,7 @@ void ARMTargetELFStreamer::finishAttributeSection() {
void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
ARMELFStreamer &Streamer = getStreamer();
- if (!Streamer.IsThumb)
+ if (!Streamer.getIsThumbFlag())
return;
Streamer.ThumbLabels.insert(Symbol);
@@ -1226,8 +1232,8 @@ void ARMELFStreamer::EHReset() {
FPOffset = 0;
SPOffset = 0;
PendingOffset = 0;
- UsedFP = false;
- CantUnwind = false;
+ setUsedFP(false);
+ setCantUnwind(false);
Opcodes.clear();
UnwindOpAsm.Reset();
@@ -1243,7 +1249,7 @@ void ARMELFStreamer::emitFnEnd() {
assert(FnStart && ".fnstart must precedes .fnend");
// Emit unwind opcodes if there is no .handlerdata directive
- if (!ExTab && !CantUnwind)
+ if (!ExTab && !getCantUnwind())
FlushUnwindOpcodes(true);
// Emit the exception index table entry
@@ -1254,7 +1260,7 @@ void ARMELFStreamer::emitFnEnd() {
// linker garbage collection. We disable this for Android where the unwinder
// is either dynamically linked or directly references the personality
// routine.
- if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
+ if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !getIsAndroid())
EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
const MCSymbolRefExpr *FnStartRef =
@@ -1262,7 +1268,7 @@ void ARMELFStreamer::emitFnEnd() {
emitValue(FnStartRef, 4);
- if (CantUnwind) {
+ if (getCantUnwind()) {
emitInt32(ARM::EHABI::EXIDX_CANTUNWIND);
} else if (ExTab) {
// Emit a reference to the unwind opcodes in the ".ARM.extab" section.
@@ -1291,7 +1297,7 @@ void ARMELFStreamer::emitFnEnd() {
EHReset();
}
-void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
+void ARMELFStreamer::emitCantUnwind() { setCantUnwind(true); }
// Add the R_ARM_NONE fixup at the same position
void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
@@ -1312,7 +1318,7 @@ void ARMELFStreamer::FlushPendingOffset() {
void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
// Emit the unwind opcode to restore $sp.
- if (UsedFP) {
+ if (getUsedFP()) {
const MCRegisterInfo *MRI = getContext().getRegisterInfo();
int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
@@ -1322,7 +1328,10 @@ void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
}
// Finalize the unwind opcode sequence
- UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
+ SmallVector<uint8_t, 64> UnwindOpcodes;
+ UnwindOpcodes = std::move(Opcodes);
+ UnwindOpAsm.Finalize(PersonalityIndex, UnwindOpcodes);
+ Opcodes.assign(std::move(UnwindOpcodes));
// For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
// section. Thus, we don't have to create an entry in the .ARM.extab
@@ -1385,7 +1394,7 @@ void ARMELFStreamer::emitSetFP(MCRegister NewFPReg, MCRegister NewSPReg,
assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
"the operand of .setfp directive should be either $sp or $fp");
- UsedFP = true;
+ setUsedFP(true);
FPReg = NewFPReg;
if (NewSPReg == ARM::SP)
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
index cea173231f3bc..b7a33fa380700 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
@@ -380,7 +380,7 @@ void ARMInstPrinter::printOperand(const MCInst *MI, uint64_t Address,
unsigned OpNum, const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNum);
- if (!Op.isImm() || !PrintBranchImmAsAddress || getUseMarkup())
+ if (!Op.isImm() || !getPrintBranchImmAsAddress() || getUseMarkup())
return printOperand(MI, OpNum, STI, O);
uint64_t Target = ARM_MC::evaluateBranchTarget(MII.get(MI->getOpcode()),
Address, Op.getImm());
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp
index 1a329fd8fde36..118d0886b8a62 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp
@@ -159,7 +159,7 @@ void UnwindOpcodeAssembler::Finalize(unsigned &PersonalityIndex,
SmallVectorImpl<uint8_t> &Result) {
UnwindOpcodeStreamer OpStreamer(Result);
- if (HasPersonality) {
+ if (getHasPersonality()) {
// User-specified personality routine: [ SIZE , OP1 , OP2 , ... ]
PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
size_t TotalSize = Ops.size() + 1;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
index 9d35626f449de..688895c0a8073 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <cstddef>
#include <cstdint>
@@ -26,8 +27,9 @@ class MCSymbol;
class UnwindOpcodeAssembler {
private:
SmallVector<uint8_t, 32> Ops;
- SmallVector<unsigned, 8> OpBegins;
- bool HasPersonality = false;
+ llvm::SmallVectorWithFlags<unsigned, 8> OpBegins;
+ bool getHasPersonality() const { return OpBegins.getFlag(0); }
+ void setHasPersonality(bool Value) { OpBegins.setFlag(0, Value); }
public:
UnwindOpcodeAssembler() {
@@ -39,13 +41,11 @@ class UnwindOpcodeAssembler {
Ops.clear();
OpBegins.clear();
OpBegins.push_back(0);
- HasPersonality = false;
+ setHasPersonality(false);
}
/// Set the personality
- void setPersonality(const MCSymbol *Per) {
- HasPersonality = true;
- }
+ void setPersonality(const MCSymbol *Per) { setHasPersonality(true); }
/// Emit unwind opcodes for .save directives
void EmitRegSave(uint32_t RegSave);
diff --git a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp
index aa7e9c40db806..3cb103ba6fae4 100644
--- a/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/llvm/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -213,14 +214,20 @@ namespace {
/// ReduceMBB - Reduce width of instructions in the specified basic block.
bool ReduceMBB(MachineBasicBlock &MBB, bool SkipPrologueEpilogue);
- bool OptimizeSize;
- bool MinimizeSize;
+ bool getOptimizeSize() const { return BlockInfo.getFlag(0); }
+ void setOptimizeSize(bool Value) { BlockInfo.setFlag(0, Value); }
+ bool getMinimizeSize() const { return BlockInfo.getFlag(1); }
+ bool setMinimizeSize(bool Value) {
+ BlockInfo.setFlag(1, Value);
+ return Value;
+ }
// Last instruction to define CPSR in the current block.
MachineInstr *CPSRDef;
// Was CPSR last defined by a high latency instruction?
// When CPSRDef is null, this refers to CPSR defs in predecessors.
- bool HighLatencyCPSR;
+ bool getHighLatencyCPSR() const { return BlockInfo.getFlag(2); }
+ void setHighLatencyCPSR(bool Value) { BlockInfo.setFlag(2, Value); }
struct MBBInfo {
// The flags leaving this block have high latency.
@@ -231,7 +238,7 @@ namespace {
MBBInfo() = default;
};
- SmallVector<MBBInfo, 8> BlockInfo;
+ llvm::SmallVectorWithFlags<MBBInfo, 8, 3> BlockInfo;
std::function<bool(const Function &)> PredicateFtor;
};
@@ -245,7 +252,7 @@ INITIALIZE_PASS(Thumb2SizeReduce, DEBUG_TYPE, THUMB2_SIZE_REDUCE_NAME, false,
Thumb2SizeReduce::Thumb2SizeReduce(std::function<bool(const Function &)> Ftor)
: MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
- OptimizeSize = MinimizeSize = false;
+ setOptimizeSize(setMinimizeSize(false));
for (unsigned i = 0, e = std::size(ReduceTable); i != e; ++i) {
unsigned FromOpc = ReduceTable[i].WideOpc;
if (!ReduceOpcodeMap.insert(std::make_pair(FromOpc, i)).second)
@@ -287,13 +294,13 @@ static bool isHighLatencyCPSR(const MachineInstr *Def) {
bool Thumb2SizeReduce::canAddPseudoFlagDep(const MachineInstr *Use,
bool FirstInSelfLoop) {
// Disable the check for -Oz (aka OptimizeForSizeHarder).
- if (MinimizeSize || !STI->avoidCPSRPartialUpdate())
+ if (getMinimizeSize() || !STI->avoidCPSRPartialUpdate())
return false;
if (!CPSRDef)
// If this BB loops back to itself, conservatively avoid narrowing the
// first instruction that does partial flag update.
- return HighLatencyCPSR || FirstInSelfLoop;
+ return getHighLatencyCPSR() || FirstInSelfLoop;
SmallSet<unsigned, 2> Defs;
for (const MachineOperand &MO : CPSRDef->operands()) {
@@ -314,7 +321,7 @@ bool Thumb2SizeReduce::canAddPseudoFlagDep(const MachineInstr *Use,
}
// If the current CPSR has high latency, try to avoid the false dependency.
- if (HighLatencyCPSR)
+ if (getHighLatencyCPSR())
return true;
// tMOVi8 usually doesn't start long dependency chains, and there are a lot
@@ -452,7 +459,7 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
break;
case ARM::t2LDR_POST:
case ARM::t2STR_POST: {
- if (!MinimizeSize)
+ if (!getMinimizeSize())
return false;
if (!MI->hasOneMemOperand() ||
@@ -747,7 +754,7 @@ Thumb2SizeReduce::ReduceTo2Addr(MachineBasicBlock &MBB, MachineInstr *MI,
if (ReduceLimit2Addr != -1 && ((int)Num2Addrs >= ReduceLimit2Addr))
return false;
- if (!OptimizeSize && Entry.AvoidMovs && STI->avoidMOVsShifterOperand())
+ if (!getOptimizeSize() && Entry.AvoidMovs && STI->avoidMOVsShifterOperand())
// Don't issue movs with shifter operand for some CPUs unless we
// are optimizing for size.
return false;
@@ -757,7 +764,7 @@ Thumb2SizeReduce::ReduceTo2Addr(MachineBasicBlock &MBB, MachineInstr *MI,
// t2MUL is "special". The tied source operand is second, not first.
if (MI->getOpcode() == ARM::t2MUL) {
// MULS can be slower than MUL
- if (!MinimizeSize && STI->avoidMULS())
+ if (!getMinimizeSize() && STI->avoidMULS())
return false;
Register Reg2 = MI->getOperand(2).getReg();
// Early exit if the regs aren't all low regs.
@@ -865,7 +872,7 @@ Thumb2SizeReduce::ReduceToNarrow(MachineBasicBlock &MBB, MachineInstr *MI,
if (ReduceLimit != -1 && ((int)NumNarrows >= ReduceLimit))
return false;
- if (!OptimizeSize && Entry.AvoidMovs && STI->avoidMOVsShifterOperand())
+ if (!getOptimizeSize() && Entry.AvoidMovs && STI->avoidMOVsShifterOperand())
// Don't issue movs with shifter operand for some CPUs unless we
// are optimizing for size.
return false;
@@ -1031,7 +1038,7 @@ bool Thumb2SizeReduce::ReduceMBB(MachineBasicBlock &MBB,
}
CPSRDef = nullptr;
- HighLatencyCPSR = false;
+ setHighLatencyCPSR(false);
// Check predecessors for the latest CPSRDef.
for (auto *Pred : MBB.predecessors()) {
@@ -1042,7 +1049,7 @@ bool Thumb2SizeReduce::ReduceMBB(MachineBasicBlock &MBB,
}
if (PInfo.HighLatencyCPSR) {
- HighLatencyCPSR = true;
+ setHighLatencyCPSR(true);
break;
}
}
@@ -1080,18 +1087,18 @@ bool Thumb2SizeReduce::ReduceMBB(MachineBasicBlock &MBB,
if (MI->isCall()) {
// Calls don't really set CPSR.
CPSRDef = nullptr;
- HighLatencyCPSR = false;
+ setHighLatencyCPSR(false);
IsSelfLoop = false;
} else if (MI->definesRegister(ARM::CPSR, /*TRI=*/nullptr)) {
// This is the last CPSR defining instruction.
CPSRDef = MI;
- HighLatencyCPSR = isHighLatencyCPSR(CPSRDef);
+ setHighLatencyCPSR(isHighLatencyCPSR(CPSRDef));
IsSelfLoop = false;
}
}
MBBInfo &Info = BlockInfo[MBB.getNumber()];
- Info.HighLatencyCPSR = HighLatencyCPSR;
+ Info.HighLatencyCPSR = getHighLatencyCPSR();
Info.Visited = true;
return Modified;
}
@@ -1107,8 +1114,8 @@ bool Thumb2SizeReduce::runOnMachineFunction(MachineFunction &MF) {
TII = static_cast<const Thumb2InstrInfo *>(STI->getInstrInfo());
// Optimizing / minimizing size? Minimizing size implies optimizing for size.
- OptimizeSize = MF.getFunction().hasOptSize();
- MinimizeSize = STI->hasMinSize();
+ setOptimizeSize(MF.getFunction().hasOptSize());
+ setMinimizeSize(STI->hasMinSize());
BlockInfo.clear();
BlockInfo.resize(MF.getNumBlockIDs());
diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index bb7caa275718a..10f51ab1ba54c 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -1278,10 +1278,10 @@ static_assert(std::size(RegList8Tiny) == std::size(RegList16Tiny),
/// to handle special constraints in the ABI.
/// In addition, all pieces of a certain argument have to be passed either
/// using registers or the stack but never mixing both.
-template <typename ArgT>
+template <typename ArgRangeT>
static void analyzeArguments(TargetLowering::CallLoweringInfo *CLI,
const Function *F, const DataLayout *TD,
- const SmallVectorImpl<ArgT> &Args,
+ const ArgRangeT &Args,
SmallVectorImpl<CCValAssign> &ArgLocs,
CCState &CCInfo, bool Tiny) {
// Choose the proper register list for argument passing according to the ABI.
@@ -1357,12 +1357,11 @@ static void analyzeArguments(TargetLowering::CallLoweringInfo *CLI,
}
/// Count the total number of bytes needed to pass or return these arguments.
-template <typename ArgT>
-static unsigned
-getTotalArgumentsSizeInBytes(const SmallVectorImpl<ArgT> &Args) {
+template <typename ArgRangeT>
+static unsigned getTotalArgumentsSizeInBytes(const ArgRangeT &Args) {
unsigned TotalBytes = 0;
- for (const ArgT &Arg : Args) {
+ for (const auto &Arg : Args) {
TotalBytes += Arg.VT.getStoreSize();
}
return TotalBytes;
@@ -1371,9 +1370,9 @@ getTotalArgumentsSizeInBytes(const SmallVectorImpl<ArgT> &Args) {
/// Analyze incoming and outgoing value of returning from a function.
/// The algorithm is similar to analyzeArguments, but there can only be
/// one value, possibly an aggregate, and it is limited to 8 bytes.
-template <typename ArgT>
-static void analyzeReturnValues(const SmallVectorImpl<ArgT> &Args,
- CCState &CCInfo, bool Tiny) {
+template <typename ArgRangeT>
+static void analyzeReturnValues(const ArgRangeT &Args, CCState &CCInfo,
+ bool Tiny) {
unsigned NumArgs = Args.size();
unsigned TotalBytes = getTotalArgumentsSizeInBytes(Args);
// CanLowerReturn() guarantees this assertion.
@@ -1424,8 +1423,8 @@ static void analyzeReturnValues(const SmallVectorImpl<ArgT> &Args,
SDValue AVRTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
auto DL = DAG.getDataLayout();
@@ -1526,19 +1525,18 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
- bool &isTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
- bool isVarArg = CLI.IsVarArg;
+ bool isVarArg = CLI.getIsVarArg();
MachineFunction &MF = DAG.getMachineFunction();
// AVR does not yet support tail call optimization.
- isTailCall = false;
+ CLI.setIsTailCall(false);
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -1702,8 +1700,8 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
///
SDValue AVRTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
@@ -1733,10 +1731,11 @@ SDValue AVRTargetLowering::LowerCallResult(
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
-bool AVRTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool AVRTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
if (CallConv == CallingConv::AVR_BUILTIN) {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
@@ -1747,12 +1746,12 @@ bool AVRTargetLowering::CanLowerReturn(
return TotalBytes <= (unsigned)(Subtarget.hasTinyEncoding() ? 4 : 8);
}
-SDValue
-AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &dl, SelectionDAG &DAG) const {
+SDValue AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &dl,
+ SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of the return value to locations.
SmallVector<CCValAssign, 16> RVLocs;
diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h
index 4ad386db00183..affd1c1aac187 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.h
+++ b/llvm/lib/Target/AVR/AVRISelLowering.h
@@ -112,25 +112,23 @@ class AVRTargetLowering : public TargetLowering {
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
SelectionDAG &DAG) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
protected:
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp b/llvm/lib/Target/BPF/BPFISelLowering.cpp
index 435f0e15a25c5..c523e7525c61c 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.cpp
+++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp
@@ -407,8 +407,8 @@ static SDValue convertLocValType(SelectionDAG &DAG, const SDLoc &DL,
SDValue BPFTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
switch (CallConv) {
default:
report_fatal_error("unimplemented calling convention: " + Twine(CallConv));
@@ -502,13 +502,12 @@ SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
- bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
MachineFunction &MF = DAG.getMachineFunction();
// BPF target does not support tail call optimization.
- IsTailCall = false;
+ CLI.setIsTailCall(false);
switch (CallConv) {
default:
@@ -649,7 +648,7 @@ SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Chain = DAG.getNode(BPFISD::CALL, CLI.DL, NodeTys, Ops);
InGlue = Chain.getValue(1);
- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.getNoMerge());
// Create the CALLSEQ_END node.
Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, CLI.DL);
@@ -661,12 +660,12 @@ SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
InVals);
}
-SDValue
-BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &DL, SelectionDAG &DAG) const {
+SDValue BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL,
+ SelectionDAG &DAG) const {
unsigned Opc = BPFISD::RET_GLUE;
// CCValAssign - represent the assignment of the return value to a location
@@ -707,8 +706,8 @@ BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
SDValue BPFTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
// Assign locations to each value returned by this call.
@@ -860,12 +859,12 @@ SDValue BPFTargetLowering::LowerTRAP(SDValue Op, SelectionDAG &DAG) const {
auto PtrVT = getPointerTy(MF.getDataLayout());
CLI.Callee = DAG.getTargetGlobalAddress(Fn, DL, PtrVT);
CLI.Chain = N->getOperand(0);
- CLI.IsTailCall = false;
+ CLI.setIsTailCall(false);
CLI.CallConv = CallingConv::C;
- CLI.IsVarArg = false;
+ CLI.setIsVarArg(false);
CLI.DL = std::move(DL);
- CLI.NoMerge = false;
- CLI.DoesNotReturn = true;
+ CLI.setNoMerge(false);
+ CLI.setDoesNotReturn(true);
return LowerCall(CLI, InVals);
}
@@ -1248,10 +1247,11 @@ bool BPFTargetLowering::isLegalAddressingMode(const DataLayout &DL,
return true;
}
-bool BPFTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool BPFTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, getHasAlu32() ? RetCC_BPF32 : RetCC_BPF64);
diff --git a/llvm/lib/Target/BPF/BPFISelLowering.h b/llvm/lib/Target/BPF/BPFISelLowering.h
index 8c00c8caa5bcd..fe39d39f36382 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.h
+++ b/llvm/lib/Target/BPF/BPFISelLowering.h
@@ -97,8 +97,8 @@ class BPFTargetLowering : public TargetLowering {
// Lower the result values of a call, copying them out of physregs into vregs
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &DL, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
// Lower a call into CALLSEQ_START - BPFISD:CALL - CALLSEQ_END chain
@@ -107,13 +107,12 @@ class BPFTargetLowering : public TargetLowering {
// Lower incoming arguments, copy physregs into vregs
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool IsVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
@@ -169,8 +168,7 @@ class BPFTargetLowering : public TargetLowering {
MachineBasicBlock *BB) const;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
};
}
diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index 7ddeedb838e87..57ccfb11a1f92 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -618,8 +618,9 @@ BTFTypeFuncProto::BTFTypeFuncProto(
bool UseFilteredParams, ArrayRef<uint32_t> AliveParamIndices,
bool VoidReturn)
: STy(STy), FuncArgNames(FuncArgNames),
- AliveParamIndices(AliveParamIndices),
- UseFilteredParams(UseFilteredParams), VoidReturn(VoidReturn) {
+ AliveParamIndices(decltype(this->AliveParamIndices)::withFlags(
+ unsigned(UseFilteredParams) | (unsigned(VoidReturn) << 1),
+ AliveParamIndices)) {
Kind = BTF::BTF_KIND_FUNC_PROTO;
BTFType.Info = (Kind << 24) | VLen;
}
@@ -630,7 +631,7 @@ void BTFTypeFuncProto::completeType(BTFDebug &BDebug) {
IsCompleted = true;
DITypeArray Elements = STy->getTypeArray();
- if (VoidReturn) {
+ if (getVoidReturn()) {
BTFType.Type = 0;
} else {
auto RetType = tryRemoveAtomicType(Elements[0]);
@@ -653,7 +654,7 @@ void BTFTypeFuncProto::completeType(BTFDebug &BDebug) {
Parameters.push_back(Param);
};
- if (UseFilteredParams) {
+ if (getUseFilteredParams()) {
for (uint32_t I : AliveParamIndices)
EmitParam(I);
return;
diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h
index b29a0cb88624d..2d67e92279271 100644
--- a/llvm/lib/Target/BPF/BTFDebug.h
+++ b/llvm/lib/Target/BPF/BTFDebug.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/CodeGen/DebugHandlerBase.h"
#include "llvm/DebugInfo/BTF/BTF.h"
@@ -145,10 +146,12 @@ class BTFTypeStruct : public BTFTypeBase {
class BTFTypeFuncProto : public BTFTypeBase {
const DISubroutineType *STy;
SmallDenseMap<uint32_t, StringRef> FuncArgNames;
- SmallVector<uint32_t, 8> AliveParamIndices;
- bool UseFilteredParams = false;
+ llvm::SmallVectorWithFlags<uint32_t, 8, 2> AliveParamIndices;
+ bool getUseFilteredParams() const { return AliveParamIndices.getFlag(0); }
+ void setUseFilteredParams(bool Value) { AliveParamIndices.setFlag(0, Value); }
std::vector<struct BTF::BTFParam> Parameters;
- bool VoidReturn = false;
+ bool getVoidReturn() const { return AliveParamIndices.getFlag(1); }
+ void setVoidReturn(bool Value) { AliveParamIndices.setFlag(1, Value); }
public:
BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,
diff --git a/llvm/lib/Target/CSKY/CSKYISelLowering.cpp b/llvm/lib/Target/CSKY/CSKYISelLowering.cpp
index 8b0bb2e28ad19..24bea13088c5e 100644
--- a/llvm/lib/Target/CSKY/CSKYISelLowering.cpp
+++ b/llvm/lib/Target/CSKY/CSKYISelLowering.cpp
@@ -327,8 +327,8 @@ static SDValue unpack64(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA,
// Transform physical registers into virtual registers.
SDValue CSKYTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
switch (CallConv) {
default:
@@ -425,21 +425,22 @@ SDValue CSKYTargetLowering::LowerFormalArguments(
return Chain;
}
-bool CSKYTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool CSKYTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> CSKYLocs;
CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);
return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
}
-SDValue
-CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &DL, SelectionDAG &DAG) const {
+SDValue CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL,
+ SelectionDAG &DAG) const {
// Stores the assignment of the return value to a location.
SmallVector<CCValAssign, 16> CSKYLocs;
@@ -508,14 +509,13 @@ SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
- bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
EVT PtrVT = getPointerTy(DAG.getDataLayout());
MVT XLenVT = MVT::i32;
@@ -528,10 +528,10 @@ SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
ArgCCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, IsVarArg));
// Check if it's really possible to do a tail call.
- if (IsTailCall)
- IsTailCall = false; // TODO: TailCallOptimization;
+ if (CLI.getIsTailCall())
+ CLI.setIsTailCall(false); // TODO: TailCallOptimization;
- if (IsTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
else if (CLI.CB && CLI.CB->isMustTailCall())
report_fatal_error("failed to perform tail call elimination on a call "
@@ -558,12 +558,13 @@ SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment, Alignment,
/*IsVolatile=*/false,
- /*AlwaysInline=*/false, /*CI=*/nullptr, IsTailCall,
- MachinePointerInfo(), MachinePointerInfo());
+ /*AlwaysInline=*/false, /*CI=*/nullptr,
+ CLI.getIsTailCall(), MachinePointerInfo(),
+ MachinePointerInfo());
ByValArgs.push_back(FIPtr);
}
- if (!IsTailCall)
+ if (!CLI.getIsTailCall())
Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
// Copy argument values to their designated locations.
@@ -615,8 +616,8 @@ SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
} else {
assert(VA.isMemLoc() && "Argument not register or memory");
- assert(!IsTailCall && "Tail call not allowed if stack is used "
- "for passing parameters");
+ assert(!CLI.getIsTailCall() && "Tail call not allowed if stack is used "
+ "for passing parameters");
// Work out the address of the stack slot.
if (!StackPtr.getNode())
@@ -684,7 +685,7 @@ SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
for (auto &Reg : RegsToPass)
Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
- if (!IsTailCall) {
+ if (!CLI.getIsTailCall()) {
// Add a register mask operand representing the call-preserved registers.
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
@@ -699,7 +700,7 @@ SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
// Emit the call.
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
MF.getFrameInfo().setHasTailCall();
return DAG.getNode(IsRegCall ? CSKYISD::TAILReg : CSKYISD::TAIL, DL,
NodeTys, Ops);
@@ -707,7 +708,7 @@ SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
Chain = DAG.getNode(IsRegCall ? CSKYISD::CALLReg : CSKYISD::CALL, DL, NodeTys,
Ops);
- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.getNoMerge());
Glue = Chain.getValue(1);
// Mark the end of the call, which is glued to the call itself.
diff --git a/llvm/lib/Target/CSKY/CSKYISelLowering.h b/llvm/lib/Target/CSKY/CSKYISelLowering.h
index ecd2ad96ae179..7f6922f5a5a71 100644
--- a/llvm/lib/Target/CSKY/CSKYISelLowering.h
+++ b/llvm/lib/Target/CSKY/CSKYISelLowering.h
@@ -36,18 +36,16 @@ class CSKYTargetLowering : public TargetLowering {
private:
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool IsVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp
index 90428e34cefa3..74627fe902679 100644
--- a/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp
+++ b/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp
@@ -83,7 +83,7 @@ void CSKYInstPrinter::printInst(const MCInst *MI, uint64_t Address,
}
void CSKYInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) {
- if (PrintBranchImmAsAddress)
+ if (getPrintBranchImmAsAddress())
O << getRegisterName(Reg, ABIRegNames ? CSKY::ABIRegAltName
: CSKY::NoRegAltName);
else
@@ -91,7 +91,7 @@ void CSKYInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) {
}
void CSKYInstPrinter::printFPRRegName(raw_ostream &O, unsigned RegNo) const {
- if (PrintBranchImmAsAddress)
+ if (getPrintBranchImmAsAddress())
O << getRegisterName(RegNo, CSKY::NoRegAltName);
else
O << getRegisterName(RegNo);
@@ -104,7 +104,7 @@ void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
if (MO.isReg()) {
unsigned Reg = MO.getReg();
bool useABIName = false;
- if (PrintBranchImmAsAddress)
+ if (getPrintBranchImmAsAddress())
useABIName = ABIRegNames;
else
useABIName = !ArchRegNames;
@@ -130,7 +130,7 @@ void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
uint64_t TSFlags = MII.get(MI->getOpcode()).TSFlags;
if (((TSFlags & CSKYII::AddrModeMask) != CSKYII::AddrModeNone) &&
- PrintBranchImmAsAddress)
+ getPrintBranchImmAsAddress())
O << formatHex(MO.getImm());
else
O << MO.getImm();
@@ -160,7 +160,7 @@ void CSKYInstPrinter::printConstpool(const MCInst *MI, uint64_t Address,
const MCOperand &MO = MI->getOperand(OpNo);
if (MO.isImm()) {
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address + MO.getImm();
Target &= 0xfffffffc;
O << formatHex(Target);
@@ -186,7 +186,7 @@ void CSKYInstPrinter::printCSKYSymbolOperand(const MCInst *MI, uint64_t Address,
return printOperand(MI, OpNo, STI, O);
}
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address + MO.getImm();
Target &= 0xffffffff;
O << formatHex(Target);
diff --git a/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
index 1dabcf32fa8e8..8193ea2563550 100644
--- a/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp
@@ -15,6 +15,7 @@
#include "HexagonSubtarget.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -54,10 +55,13 @@ class HexagonCopyToCombine : public MachineFunctionPass {
const HexagonInstrInfo *TII;
const TargetRegisterInfo *TRI;
const HexagonSubtarget *ST;
- bool ShouldCombineAggressively;
+ bool getShouldCombineAggressively() const { return DbgMItoMove.getFlag(0); }
+ void setShouldCombineAggressively(bool Value) {
+ DbgMItoMove.setFlag(0, Value);
+ }
DenseSet<MachineInstr *> PotentiallyNewifiableTFR;
- SmallVector<MachineInstr *, 8> DbgMItoMove;
+ llvm::SmallVectorWithFlags<MachineInstr *, 8> DbgMItoMove;
public:
static char ID;
@@ -270,7 +274,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1,
MachineBasicBlock::reverse_iterator I = ++I2.getIterator().getReverse();
MachineBasicBlock::reverse_iterator End = I1.getIterator().getReverse();
// At 03 we got better results (dhrystone!) by being more conservative.
- if (!ShouldCombineAggressively)
+ if (!getShouldCombineAggressively())
End = ++I1.getIterator().getReverse();
// If I2 kills its operand and we move I2 over an instruction that also
// uses I2's use reg we need to modify that (first) instruction to now kill
@@ -318,7 +322,7 @@ bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1,
// Look at instructions I in between I1 and (excluding) I2.
MachineBasicBlock::iterator I(I1), End(I2);
// At O3 we got better results (dhrystone) by being more conservative here.
- if (!ShouldCombineAggressively)
+ if (!getShouldCombineAggressively())
End = std::next(MachineBasicBlock::iterator(I2));
Register I1UseReg = UseReg(I1.getOperand(1));
// Track killed operands. If we move across an instruction that kills our
@@ -400,7 +404,8 @@ HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
MachineInstr *DefInst = LastDef[Reg];
if (!DefInst)
continue;
- if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively))
+ if (!isCombinableInstType(*DefInst, TII,
+ getShouldCombineAggressively()))
continue;
// Only close newifiable stores should influence the decision.
@@ -460,8 +465,8 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
bool OptForSize = F.hasOptSize();
// Combine aggressively (for code size)
- ShouldCombineAggressively =
- MF.getTarget().getOptLevel() <= CodeGenOptLevel::Default;
+ setShouldCombineAggressively(MF.getTarget().getOptLevel() <=
+ CodeGenOptLevel::Default);
// Disable CONST64 for tiny core since it takes a LD resource.
if (!OptForSize && ST->isTinyCore())
@@ -483,11 +488,11 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
// Don't combine a TFR whose user could be newified (instructions that
// define double registers can not be newified - Programmer's Ref Manual
// 5.4.2 New-value stores).
- if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1))
+ if (getShouldCombineAggressively() && PotentiallyNewifiableTFR.count(&I1))
continue;
// Ignore instructions that are not combinable.
- if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))
+ if (!isCombinableInstType(I1, TII, getShouldCombineAggressively()))
continue;
// Find a second instruction that can be merged into a combine
@@ -526,11 +531,11 @@ MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1,
break;
// Ignore non-combinable instructions.
- if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively))
+ if (!isCombinableInstType(*I2, TII, getShouldCombineAggressively()))
continue;
// Don't combine a TFR whose user could be newified.
- if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2))
+ if (getShouldCombineAggressively() && PotentiallyNewifiableTFR.count(&*I2))
continue;
Register I2DestReg = I2->getOperand(0).getReg();
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index 199edef3d05ce..24cb03fddd973 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -15,6 +15,7 @@
#include "HexagonISelLowering.h"
#include "HexagonMachineFunctionInfo.h"
#include "HexagonTargetMachine.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
@@ -1822,33 +1823,28 @@ struct WeightedLeaf {
/// constants and allows removal of non-top elements while maintaining the
/// priority order.
class LeafPrioQueue {
- SmallVector<WeightedLeaf, 8> Q;
- bool HaveConst;
+ llvm::SmallVectorWithFlags<WeightedLeaf, 8> Q;
+ bool getHaveConst() const { return Q.getFlag(0); }
+ void setHaveConst(bool Value) { Q.setFlag(0, Value); }
WeightedLeaf ConstElt;
unsigned Opcode;
public:
- bool empty() {
- return (!HaveConst && Q.empty());
- }
+ bool empty() { return (!getHaveConst() && Q.empty()); }
- size_t size() {
- return Q.size() + HaveConst;
- }
+ size_t size() { return Q.size() + getHaveConst(); }
- bool hasConst() {
- return HaveConst;
- }
+ bool hasConst() { return getHaveConst(); }
const WeightedLeaf &top() {
- if (HaveConst)
+ if (getHaveConst())
return ConstElt;
return Q.front();
}
WeightedLeaf pop() {
- if (HaveConst) {
- HaveConst = false;
+ if (getHaveConst()) {
+ setHaveConst(false);
return ConstElt;
}
std::pop_heap(Q.begin(), Q.end(), WeightedLeaf::Compare);
@@ -1856,7 +1852,7 @@ class LeafPrioQueue {
}
void push(WeightedLeaf L, bool SeparateConst=true) {
- if (!HaveConst && SeparateConst && isa<ConstantSDNode>(L.Value)) {
+ if (!getHaveConst() && SeparateConst && isa<ConstantSDNode>(L.Value)) {
if (Opcode == ISD::MUL &&
cast<ConstantSDNode>(L.Value)->getSExtValue() == 1)
return;
@@ -1864,7 +1860,7 @@ class LeafPrioQueue {
cast<ConstantSDNode>(L.Value)->getSExtValue() == 0)
return;
- HaveConst = true;
+ setHaveConst(true);
ConstElt = L;
} else {
Q.push_back(L);
@@ -1885,8 +1881,7 @@ class LeafPrioQueue {
WeightedLeaf findMULbyConst();
- LeafPrioQueue(unsigned Opcode) :
- HaveConst(false), Opcode(Opcode) { }
+ LeafPrioQueue(unsigned Opcode) : Opcode(Opcode) {}
};
} // end anonymous namespace
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index b6e16893bc134..cb5580a016b2e 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -223,11 +223,11 @@ static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst,
MachinePointerInfo());
}
-bool
-HexagonTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- LLVMContext &Context, const Type *RetTy) const {
+bool HexagonTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
@@ -242,7 +242,7 @@ HexagonTargetLowering::CanLowerReturn(
SDValue
HexagonTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of the return value to locations.
@@ -387,9 +387,9 @@ Register HexagonTargetLowering::getRegisterByName(
/// ISD::CALL.
SDValue HexagonTargetLowering::LowerCallResult(
SDValue Chain, SDValue Glue, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
- const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals, const SmallVectorImpl<SDValue> &OutVals,
+ SDValue Callee) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
@@ -443,14 +443,14 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &dl = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
- bool DoesNotReturn = CLI.DoesNotReturn;
+ bool IsVarArg = CLI.getIsVarArg();
+ bool DoesNotReturn = CLI.getDoesNotReturn();
bool IsStructRet = Outs.empty() ? false : Outs[0].Flags.isSRet();
MachineFunction &MF = DAG.getMachineFunction();
@@ -474,20 +474,21 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
else
CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon);
- if (CLI.IsTailCall) {
+ if (CLI.getIsTailCall()) {
bool StructAttrFlag = MF.getFunction().hasStructRetAttr();
- CLI.IsTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
- IsVarArg, IsStructRet, StructAttrFlag, Outs,
- OutVals, Ins, DAG);
+ CLI.setIsTailCall(IsEligibleForTailCallOptimization(
+ Callee, CallConv, IsVarArg, IsStructRet, StructAttrFlag, Outs, OutVals,
+ Ins, DAG));
for (const CCValAssign &VA : ArgLocs) {
if (VA.isMemLoc()) {
- CLI.IsTailCall = false;
+ CLI.setIsTailCall(false);
break;
}
}
- LLVM_DEBUG(dbgs() << (CLI.IsTailCall ? "Eligible for Tail Call\n"
- : "Argument must be passed on stack. "
- "Not eligible for Tail Call\n"));
+ LLVM_DEBUG(dbgs() << (CLI.getIsTailCall()
+ ? "Eligible for Tail Call\n"
+ : "Argument must be passed on stack. "
+ "Not eligible for Tail Call\n"));
}
// Get a count of how many bytes are to be pushed on the stack.
unsigned NumBytes = CCInfo.getStackSize();
@@ -570,7 +571,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
SDValue Glue;
- if (!CLI.IsTailCall) {
+ if (!CLI.getIsTailCall()) {
Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
Glue = Chain.getValue(1);
}
@@ -579,7 +580,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// chain and flag operands which copy the outgoing args into registers.
// The Glue is necessary since all emitted instructions must be
// stuck together.
- if (!CLI.IsTailCall) {
+ if (!CLI.getIsTailCall()) {
for (const auto &R : RegsToPass) {
Chain = DAG.getCopyToReg(Chain, dl, R.first, R.second, Glue);
Glue = Chain.getValue(1);
@@ -633,7 +634,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (Glue.getNode())
Ops.push_back(Glue);
- if (CLI.IsTailCall) {
+ if (CLI.getIsTailCall()) {
MFI.setHasTailCall();
return DAG.getNode(HexagonISD::TC_RETURN, dl, MVT::Other, Ops);
}
@@ -844,8 +845,8 @@ SDValue HexagonTargetLowering::LowerFMINFMAX(SDValue Op,
SDValue HexagonTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -3786,15 +3787,11 @@ bool HexagonTargetLowering::isLegalICmpImmediate(int64_t Imm) const {
/// for tail call optimization. Targets which want to do tail call
/// optimization should implement this function.
bool HexagonTargetLowering::IsEligibleForTailCallOptimization(
- SDValue Callee,
- CallingConv::ID CalleeCC,
- bool IsVarArg,
- bool IsCalleeStructRet,
- bool IsCallerStructRet,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- SelectionDAG& DAG) const {
+ SDValue Callee, CallingConv::ID CalleeCC, bool IsVarArg,
+ bool IsCalleeStructRet, bool IsCallerStructRet,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ SelectionDAG &DAG) const {
const Function &CallerF = DAG.getMachineFunction().getFunction();
CallingConv::ID CallerCC = CallerF.getCallingConv();
bool CCMatch = CallerCC == CalleeCC;
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index 7754027f50258..09a62981ffa43 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -43,11 +43,12 @@ class HexagonTargetLowering : public TargetLowering {
/// IsEligibleForTailCallOptimization - Check whether the call is eligible
/// for tail call optimization. Targets which want to do tail call
/// optimization should implement this function.
- bool IsEligibleForTailCallOptimization(SDValue Callee,
- CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
- bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsEligibleForTailCallOptimization(
+ SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg,
+ bool isCalleeStructRet, bool isCallerStructRet,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
+ llvm::ArrayRef<ISD::InputArg> Ins, SelectionDAG &DAG) const;
void getTgtMemIntrinsic(SmallVectorImpl<IntrinsicInfo> &Infos,
const CallBase &I, MachineFunction &MF,
@@ -119,11 +120,10 @@ class HexagonTargetLowering : public TargetLowering {
SDValue LowerFDIV(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
- SDValue
- LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals) const override;
+ SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
@@ -142,9 +142,8 @@ class HexagonTargetLowering : public TargetLowering {
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
const SmallVectorImpl<SDValue> &OutVals,
SDValue Callee) const;
@@ -154,15 +153,14 @@ class HexagonTargetLowering : public TargetLowering {
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
- bool CanLowerReturn(CallingConv::ID CallConv,
- MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &dl, SelectionDAG &DAG) const override;
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
+ SelectionDAG &DAG) const override;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
index 5831bd8685f72..dbf9a749aca3d 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
@@ -383,8 +383,8 @@ static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT,
SDValue LanaiTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
switch (CallConv) {
case CallingConv::C:
case CallingConv::Fast:
@@ -398,23 +398,23 @@ SDValue LanaiTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
- bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
// Lanai target does not yet support tail call optimization.
- IsTailCall = false;
+ CLI.setIsTailCall(false);
switch (CallConv) {
case CallingConv::Fast:
case CallingConv::C:
- return LowerCCCCallTo(Chain, Callee, CallConv, IsVarArg, IsTailCall, Outs,
- OutVals, Ins, DL, DAG, InVals);
+ return LowerCCCCallTo(Chain, Callee, CallConv, IsVarArg,
+ CLI.getIsTailCall(), Outs, OutVals, Ins, DL, DAG,
+ InVals);
default:
report_fatal_error("Unsupported calling convention");
}
@@ -424,8 +424,8 @@ SDValue LanaiTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// generate load operations for arguments places on the stack.
SDValue LanaiTargetLowering::LowerCCCArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
@@ -517,10 +517,11 @@ SDValue LanaiTargetLowering::LowerCCCArguments(
return Chain;
}
-bool LanaiTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool LanaiTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
@@ -530,7 +531,7 @@ bool LanaiTargetLowering::CanLowerReturn(
SDValue
LanaiTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of the return value to a location
@@ -592,10 +593,10 @@ LanaiTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
SDValue LanaiTargetLowering::LowerCCCCallTo(
SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool IsVarArg,
- bool /*IsTailCall*/, const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ bool /*IsTailCall*/, llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
@@ -758,8 +759,8 @@ SDValue LanaiTargetLowering::LowerCCCCallTo(
// appropriate copies out of appropriate physical registers.
SDValue LanaiTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.h b/llvm/lib/Target/Lanai/LanaiISelLowering.h
index b0d5644c1c4a1..906569cfaed72 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.h
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.h
@@ -46,8 +46,7 @@ class LanaiTargetLowering : public TargetLowering {
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
Register getRegisterByName(const char *RegName, LLT VT,
@@ -72,36 +71,33 @@ class LanaiTargetLowering : public TargetLowering {
private:
SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool IsVarArg,
- bool IsTailCall,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsTailCall, llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerCCCArguments(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool IsVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &DL, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool IsVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 1d01e76a5ebd2..2f6cb55d2efd8 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -9965,9 +9965,8 @@ static bool CC_LoongArch(const DataLayout &DL, LoongArchABI::ABI ABI,
}
void LoongArchTargetLowering::analyzeInputArgs(
- MachineFunction &MF, CCState &CCInfo,
- const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,
- LoongArchCCAssignFn Fn) const {
+ MachineFunction &MF, CCState &CCInfo, llvm::ArrayRef<ISD::InputArg> Ins,
+ bool IsRet, LoongArchCCAssignFn Fn) const {
FunctionType *FType = MF.getFunction().getFunctionType();
for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
MVT ArgVT = Ins[i].VT;
@@ -9988,9 +9987,8 @@ void LoongArchTargetLowering::analyzeInputArgs(
}
void LoongArchTargetLowering::analyzeOutputArgs(
- MachineFunction &MF, CCState &CCInfo,
- const SmallVectorImpl<ISD::OutputArg> &Outs, bool IsRet,
- CallLoweringInfo *CLI, LoongArchCCAssignFn Fn) const {
+ MachineFunction &MF, CCState &CCInfo, llvm::ArrayRef<ISD::OutputArg> Outs,
+ bool IsRet, CallLoweringInfo *CLI, LoongArchCCAssignFn Fn) const {
for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
MVT ArgVT = Outs[i].VT;
Type *OrigTy = CLI ? CLI->getArgs()[Outs[i].OrigArgIndex].Ty : nullptr;
@@ -10180,8 +10178,8 @@ static bool CC_LoongArch_GHC(unsigned ValNo, MVT ValVT, MVT LocVT,
// Transform physical registers into virtual registers.
SDValue LoongArchTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
@@ -10444,16 +10442,15 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
EVT PtrVT = getPointerTy(DAG.getDataLayout());
MVT GRLenVT = Subtarget.getGRLenVT();
- bool &IsTailCall = CLI.IsTailCall;
MachineFunction &MF = DAG.getMachineFunction();
@@ -10467,10 +10464,11 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
analyzeOutputArgs(MF, ArgCCInfo, Outs, /*IsRet=*/false, &CLI, CC_LoongArch);
// Check if it's really possible to do a tail call.
- if (IsTailCall)
- IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs);
+ if (CLI.getIsTailCall())
+ CLI.setIsTailCall(
+ isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs));
- if (IsTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
else if (CLI.CB && CLI.CB->isMustTailCall())
report_fatal_error("failed to perform tail call elimination on a call "
@@ -10502,7 +10500,7 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
ByValArgs.push_back(FIPtr);
}
- if (!IsTailCall)
+ if (!CLI.getIsTailCall())
Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
// Copy argument values to their designated locations.
@@ -10556,7 +10554,7 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
// For musttail calls, reuse incoming indirect pointers instead of
// creating new stack temporaries. The incoming pointers point to the
// caller's caller's frame, which remains valid after a tail call.
- if (IsTailCall && CLI.CB && CLI.CB->isMustTailCall()) {
+ if (CLI.getIsTailCall() && CLI.CB && CLI.CB->isMustTailCall()) {
LoongArchMachineFunctionInfo *LAFI =
MF.getInfo<LoongArchMachineFunctionInfo>();
unsigned CallArgIdx = Outs[OutIdx].OrigArgIndex;
@@ -10709,7 +10707,7 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
} else {
assert(VA.isMemLoc() && "Argument not register or memory");
- assert((!IsTailCall || (CLI.CB && CLI.CB->isMustTailCall())) &&
+ assert((!CLI.getIsTailCall() || (CLI.CB && CLI.CB->isMustTailCall())) &&
"Tail call not allowed if stack is used for passing parameters");
// Work out the address of the stack slot.
@@ -10763,7 +10761,7 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
for (auto &Reg : RegsToPass)
Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
- if (!IsTailCall) {
+ if (!CLI.getIsTailCall()) {
// Add a register mask operand representing the call-preserved registers.
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
@@ -10782,26 +10780,28 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
default:
report_fatal_error("Unsupported code model");
case CodeModel::Small:
- Op = IsTailCall ? LoongArchISD::TAIL : LoongArchISD::CALL;
+ Op = CLI.getIsTailCall() ? LoongArchISD::TAIL : LoongArchISD::CALL;
break;
case CodeModel::Medium:
- Op = IsTailCall ? LoongArchISD::TAIL_MEDIUM : LoongArchISD::CALL_MEDIUM;
+ Op = CLI.getIsTailCall() ? LoongArchISD::TAIL_MEDIUM
+ : LoongArchISD::CALL_MEDIUM;
break;
case CodeModel::Large:
assert(Subtarget.is64Bit() && "Large code model requires LA64");
- Op = IsTailCall ? LoongArchISD::TAIL_LARGE : LoongArchISD::CALL_LARGE;
+ Op = CLI.getIsTailCall() ? LoongArchISD::TAIL_LARGE
+ : LoongArchISD::CALL_LARGE;
break;
}
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
MF.getFrameInfo().setHasTailCall();
SDValue Ret = DAG.getNode(Op, DL, NodeTys, Ops);
- DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.getNoMerge());
return Ret;
}
Chain = DAG.getNode(Op, DL, NodeTys, Ops);
- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.getNoMerge());
Glue = Chain.getValue(1);
// Mark the end of the call, which is glued to the call itself.
@@ -10842,7 +10842,7 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI,
bool LoongArchTargetLowering::CanLowerReturn(
CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
+ llvm::ArrayRef<ISD::OutputArg> Outs, LLVMContext &Context,
const Type *RetTy) const {
SmallVector<CCValAssign> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
@@ -10857,11 +10857,12 @@ bool LoongArchTargetLowering::CanLowerReturn(
return true;
}
-SDValue LoongArchTargetLowering::LowerReturn(
- SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
- SelectionDAG &DAG) const {
+SDValue
+LoongArchTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL, SelectionDAG &DAG) const {
// Stores the assignment of the return value to a location.
SmallVector<CCValAssign> RVLocs;
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 7c3ae7d6aac14..3805c18ff29cb 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -42,16 +42,14 @@ class LoongArchTargetLowering : public TargetLowering {
// Lower incoming arguments, copy physregs into vregs.
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool IsVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
@@ -198,12 +196,11 @@ class LoongArchTargetLowering : public TargetLowering {
bool IsRet, Type *OrigTy);
void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,
- const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,
+ llvm::ArrayRef<ISD::InputArg> Ins, bool IsRet,
LoongArchCCAssignFn Fn) const;
void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- bool IsRet, CallLoweringInfo *CLI,
- LoongArchCCAssignFn Fn) const;
+ llvm::ArrayRef<ISD::OutputArg> Outs, bool IsRet,
+ CallLoweringInfo *CLI, LoongArchCCAssignFn Fn) const;
template <class NodeTy>
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,
diff --git a/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h b/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h
index a3f5759fb87d2..f6b4e2d7f5d2b 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h
+++ b/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h
@@ -15,6 +15,7 @@
#include "LoongArchSubtarget.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -49,9 +50,10 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
/// Pairs of `jr` instructions and corresponding JTI operands, used for the
/// `annotate-tablejump` option.
- SmallVector<std::pair<MachineInstr *, int>, 4> JumpInfos;
+ llvm::SmallVectorWithFlags<std::pair<MachineInstr *, int>, 4> JumpInfos;
- bool HasDynamicAllocation = false;
+ bool getHasDynamicAllocation() const { return JumpInfos.getFlag(0); }
+ void setHasDynamicAllocation(bool Value) { JumpInfos.setFlag(0, Value); }
public:
LoongArchMachineFunctionInfo(const Function &F,
@@ -102,8 +104,8 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
MachineInstr *getJumpInfoJrMI(unsigned Idx) { return JumpInfos[Idx].first; }
int getJumpInfoJTIIndex(unsigned Idx) { return JumpInfos[Idx].second; }
- bool hasDynamicAllocation() const { return HasDynamicAllocation; }
- void setDynamicAllocation() { HasDynamicAllocation = true; }
+ bool hasDynamicAllocation() const { return getHasDynamicAllocation(); }
+ void setDynamicAllocation() { setHasDynamicAllocation(true); }
};
} // end namespace llvm
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp
index 8587e16c1cde7..c6247b1376102 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchInstPrinter.cpp
@@ -110,7 +110,7 @@ void LoongArchInstPrinter::printBranchOperand(const MCInst *MI,
const MCSubtargetInfo &STI,
raw_ostream &O) {
// Do not print the numeric target address when symbolizing.
- if (SymbolizeOperands)
+ if (getSymbolizeOperands())
return;
return printOperand(MI, OpNo, STI, O);
diff --git a/llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp b/llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp
index 587906093cebf..6bdb61472ca9b 100644
--- a/llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp
+++ b/llvm/lib/Target/M68k/GISel/M68kCallLowering.cpp
@@ -219,7 +219,7 @@ bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
auto MIB = MIRBuilder.buildInstrNoInsert(Opc)
.add(Info.Callee)
.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::MIFlag::NoMerge);
CCAssignFn *AssignFn = TLI.getCCAssignFn(Info.CallConv, false, Info.IsVarArg);
diff --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp
index 7562a6ec6c790..6b6863878923a 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.cpp
+++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp
@@ -254,7 +254,7 @@ MVT M68kTargetLowering::getScalarShiftAmountTy(const DataLayout &DL,
enum StructReturnType { NotStructReturn, RegStructReturn, StackStructReturn };
static StructReturnType
-callIsStructReturn(const SmallVectorImpl<ISD::OutputArg> &Outs) {
+callIsStructReturn(llvm::ArrayRef<ISD::OutputArg> Outs) {
if (Outs.empty())
return NotStructReturn;
@@ -267,8 +267,7 @@ callIsStructReturn(const SmallVectorImpl<ISD::OutputArg> &Outs) {
}
/// Determines whether a function uses struct return semantics.
-static StructReturnType
-argsAreStructReturn(const SmallVectorImpl<ISD::InputArg> &Ins) {
+static StructReturnType argsAreStructReturn(llvm::ArrayRef<ISD::InputArg> Ins) {
if (Ins.empty())
return NotStructReturn;
@@ -450,13 +449,10 @@ SDValue M68kTargetLowering::EmitTailCallStoreRetAddr(
return Chain;
}
-SDValue
-M68kTargetLowering::LowerMemArgument(SDValue Chain, CallingConv::ID CallConv,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &DL, SelectionDAG &DAG,
- const CCValAssign &VA,
- MachineFrameInfo &MFI,
- unsigned ArgIdx) const {
+SDValue M68kTargetLowering::LowerMemArgument(
+ SDValue Chain, CallingConv::ID CallConv, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &DL, SelectionDAG &DAG, const CCValAssign &VA,
+ MachineFrameInfo &MFI, unsigned ArgIdx) const {
// Create the nodes corresponding to a load from this parameter slot.
ISD::ArgFlagsTy Flags = Ins[ArgIdx].Flags;
EVT ValVT;
@@ -545,14 +541,13 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool &IsTailCall = CLI.IsTailCall;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
MachineFunction &MF = DAG.getMachineFunction();
StructReturnType SR = callIsStructReturn(Outs);
@@ -565,7 +560,7 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
auto Attr = MF.getFunction().getFnAttribute("disable-tail-calls");
if (Attr.getValueAsBool())
- IsTailCall = false;
+ CLI.setIsTailCall(false);
// FIXME Add tailcalls support
@@ -574,20 +569,20 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Force this to be a tail call. The verifier rules are enough to ensure
// that we can lower this successfully without moving the return address
// around.
- IsTailCall = true;
- } else if (IsTailCall) {
+ CLI.setIsTailCall(true);
+ } else if (CLI.getIsTailCall()) {
// Check if it's really possible to do a tail call.
- IsTailCall = IsEligibleForTailCallOptimization(
+ CLI.setIsTailCall(IsEligibleForTailCallOptimization(
Callee, CallConv, IsVarArg, SR != NotStructReturn,
MF.getFunction().hasStructRetAttr(), CLI.RetTy, Outs, OutVals, Ins,
- DAG);
+ DAG));
// Sibcalls are automatically detected tailcalls which do not require
// ABI changes.
- if (!MF.getTarget().Options.GuaranteedTailCallOpt && IsTailCall)
+ if (!MF.getTarget().Options.GuaranteedTailCallOpt && CLI.getIsTailCall())
IsSibcall = true;
- if (IsTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
}
@@ -615,7 +610,7 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
}
int FPDiff = 0;
- if (IsTailCall && !IsSibcall && !IsMustTail) {
+ if (CLI.getIsTailCall() && !IsSibcall && !IsMustTail) {
// Lower arguments at fp - stackoffset + fpdiff.
unsigned NumBytesCallerPushed = MFI->getBytesToPopOnReturn();
@@ -649,8 +644,9 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SDValue RetFI;
// Load return address for tail calls.
- if (IsTailCall && FPDiff)
- Chain = EmitTailCallLoadRetAddr(DAG, RetFI, Chain, IsTailCall, FPDiff, DL);
+ if (CLI.getIsTailCall() && FPDiff)
+ Chain = EmitTailCallLoadRetAddr(DAG, RetFI, Chain, CLI.getIsTailCall(),
+ FPDiff, DL);
SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
SmallVector<SDValue, 8> MemOpChains;
@@ -703,7 +699,7 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (VA.isRegLoc()) {
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
- } else if (!IsSibcall && (!IsTailCall || IsByVal)) {
+ } else if (!IsSibcall && (!CLI.getIsTailCall() || IsByVal)) {
assert(VA.isMemLoc());
if (!StackPtr.getNode()) {
StackPtr = DAG.getCopyFromReg(Chain, DL, RegInfo->getStackRegister(),
@@ -732,7 +728,7 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// For tail calls lower the arguments to the 'real' stack slots. Sibcalls
// don't need this because the eligibility check rejects calls that require
// shuffling arguments passed in memory.
- if (!IsSibcall && IsTailCall) {
+ if (!IsSibcall && CLI.getIsTailCall()) {
// Force all the incoming stack arguments to be loaded from the stack
// before any new outgoing arguments are stored to the stack, because the
// outgoing stack slots may alias the incoming argument stack slots, and
@@ -836,7 +832,7 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVector<SDValue, 8> Ops;
- if (!IsSibcall && IsTailCall) {
+ if (!IsSibcall && CLI.getIsTailCall()) {
Chain = DAG.getCALLSEQ_END(Chain, NumBytesToPop, 0, InGlue, DL);
InGlue = Chain.getValue(1);
}
@@ -844,7 +840,7 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Ops.push_back(Chain);
Ops.push_back(Callee);
- if (IsTailCall)
+ if (CLI.getIsTailCall())
Ops.push_back(DAG.getConstant(FPDiff, DL, MVT::i32));
// Add argument registers to the end of the list so that they are known live
@@ -862,7 +858,7 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (InGlue.getNode())
Ops.push_back(InGlue);
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
MF.getFrameInfo().setHasTailCall();
return DAG.getNode(M68kISD::TC_RETURN, DL, MVT::Other, Ops);
}
@@ -884,7 +880,7 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
NumBytesForCalleeToPop = 0; // Callee pops nothing.
}
- if (CLI.DoesNotReturn && !getTargetMachine().Options.TrapUnreachable) {
+ if (CLI.getDoesNotReturn() && !getTargetMachine().Options.TrapUnreachable) {
// No need to reset the stack after the call if the call doesn't return. To
// make the MI verify, we'll pretend the callee does it for us.
NumBytesForCalleeToPop = NumBytes;
@@ -905,8 +901,8 @@ SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SDValue M68kTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
@@ -940,8 +936,8 @@ SDValue M68kTargetLowering::LowerCallResult(
SDValue M68kTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CCID, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
M68kMachineFunctionInfo *MMFI = MF.getInfo<M68kMachineFunctionInfo>();
// const TargetFrameLowering &TFL = *Subtarget.getFrameLowering();
@@ -1049,8 +1045,8 @@ SDValue M68kTargetLowering::LowerFormalArguments(
// Compute the set of forwarded registers. The rest are scratch.
// ??? what is this for?
- SmallVectorImpl<ForwardedRegister> &Forwards =
- MMFI->getForwardedMustTailRegParms();
+ SmallVector<ForwardedRegister, 1> Forwards;
+ Forwards = std::move(MMFI->getForwardedMustTailRegParms());
CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, CC_M68k);
// Copy all forwards from physical to virtual registers.
@@ -1060,6 +1056,7 @@ SDValue M68kTargetLowering::LowerFormalArguments(
F.VReg = MF.getRegInfo().createVirtualRegister(getRegClassFor(F.VT));
Chain = DAG.getCopyToReg(Chain, DL, F.VReg, RegVal);
}
+ MMFI->getForwardedMustTailRegParms().assign(std::move(Forwards));
}
// Some CCs need callee pop.
@@ -1082,21 +1079,22 @@ SDValue M68kTargetLowering::LowerFormalArguments(
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
-bool M68kTargetLowering::CanLowerReturn(
- CallingConv::ID CCID, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool M68kTargetLowering::CanLowerReturn(CallingConv::ID CCID,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CCID, IsVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, RetCC_M68k);
}
-SDValue
-M68kTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CCID,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &DL, SelectionDAG &DAG) const {
+SDValue M68kTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CCID,
+ bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL,
+ SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
M68kMachineFunctionInfo *MFI = MF.getInfo<M68kMachineFunctionInfo>();
@@ -1247,9 +1245,9 @@ M68kTargetLowering::GetAlignedArgumentStackSize(unsigned StackSize,
bool M68kTargetLowering::IsEligibleForTailCallOptimization(
SDValue Callee, CallingConv::ID CalleeCC, bool IsVarArg,
bool IsCalleeStructRet, bool IsCallerStructRet, Type *RetTy,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const {
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ SelectionDAG &DAG) const {
if (!mayTailCallThisCC(CalleeCC))
return false;
diff --git a/llvm/lib/Target/M68k/M68kISelLowering.h b/llvm/lib/Target/M68k/M68kISelLowering.h
index e4a92754606a0..bdf11b30e9371 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.h
+++ b/llvm/lib/Target/M68k/M68kISelLowering.h
@@ -152,7 +152,7 @@ class M68kTargetLowering : public TargetLowering {
const SDLoc &DL) const;
SDValue LowerMemArgument(SDValue Chain, CallingConv::ID CallConv,
- const SmallVectorImpl<ISD::InputArg> &ArgInfo,
+ llvm::ArrayRef<ISD::InputArg> ArgInfo,
const SDLoc &DL, SelectionDAG &DAG,
const CCValAssign &VA, MachineFrameInfo &MFI,
unsigned ArgIdx) const;
@@ -185,16 +185,15 @@ class M68kTargetLowering : public TargetLowering {
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &DL, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
/// LowerFormalArguments - transform physical registers into virtual
/// registers and generate load operations for arguments places on the stack.
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CCID,
- bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool IsVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
@@ -202,14 +201,13 @@ class M68kTargetLowering : public TargetLowering {
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
/// Lower the result values of a call into the
/// appropriate copies out of appropriate physical registers.
SDValue LowerReturn(SDValue Chain, CallingConv::ID CCID, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
@@ -250,9 +248,9 @@ class M68kTargetLowering : public TargetLowering {
bool IsEligibleForTailCallOptimization(
SDValue Callee, CallingConv::ID CalleeCC, bool IsVarArg,
bool IsCalleeStructRet, bool IsCallerStructRet, Type *RetTy,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const;
+ llvm::ArrayRef<ISD::InputArg> Ins, SelectionDAG &DAG) const;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
};
diff --git a/llvm/lib/Target/M68k/M68kMachineFunction.h b/llvm/lib/Target/M68k/M68kMachineFunction.h
index 2fefbb49ccd4f..3c8e616e25c83 100644
--- a/llvm/lib/Target/M68k/M68kMachineFunction.h
+++ b/llvm/lib/Target/M68k/M68kMachineFunction.h
@@ -14,6 +14,7 @@
#ifndef LLVM_LIB_TARGET_M68K_M68KMACHINEFUNCTION_H
#define LLVM_LIB_TARGET_M68K_M68KMACHINEFUNCTION_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
@@ -50,7 +51,12 @@ class M68kMachineFunctionInfo : public MachineFunctionInfo {
/// Keeps track of whether this function uses sequences of pushes to pass
/// function parameters.
- bool HasPushSequences = false;
+ bool getHasPushSequencesFlag() const {
+ return ForwardedMustTailRegParms.getFlag(0);
+ }
+ void setHasPushSequencesFlag(bool Value) {
+ ForwardedMustTailRegParms.setFlag(0, Value);
+ }
/// Some subtargets require that sret lowering includes
/// returning the value of the returned struct in a register. This field
@@ -59,7 +65,7 @@ class M68kMachineFunctionInfo : public MachineFunctionInfo {
/// A list of virtual and physical registers that must be forwarded to every
/// musttail call.
- SmallVector<ForwardedRegister, 1> ForwardedMustTailRegParms;
+ llvm::SmallVectorWithFlags<ForwardedRegister, 1> ForwardedMustTailRegParms;
/// The number of bytes on stack consumed by the arguments being passed on
/// the stack.
@@ -96,8 +102,8 @@ class M68kMachineFunctionInfo : public MachineFunctionInfo {
int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
- bool getHasPushSequences() const { return HasPushSequences; }
- void setHasPushSequences(bool HasPush) { HasPushSequences = HasPush; }
+ bool getHasPushSequences() const { return getHasPushSequencesFlag(); }
+ void setHasPushSequences(bool HasPush) { setHasPushSequencesFlag(HasPush); }
unsigned getSRetReturnReg() const { return SRetReturnReg; }
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
@@ -105,7 +111,7 @@ class M68kMachineFunctionInfo : public MachineFunctionInfo {
unsigned getArgumentStackSize() const { return ArgumentStackSize; }
void setArgumentStackSize(unsigned size) { ArgumentStackSize = size; }
- SmallVectorImpl<ForwardedRegister> &getForwardedMustTailRegParms() {
+ SmallVectorWithFlagsImpl<ForwardedRegister> &getForwardedMustTailRegParms() {
return ForwardedMustTailRegParms;
}
diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
index 04a8a0721e6f5..5cdbeee178e05 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -235,8 +235,8 @@ MSP430TargetLowering::getRegForInlineAsmConstraint(
/// For each argument in a function store the number of pieces it is composed
/// of.
-template<typename ArgT>
-static void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args,
+template <typename ArgRangeT>
+static void ParseFunctionArgs(const ArgRangeT &Args,
SmallVectorImpl<unsigned> &Out) {
unsigned CurrentArgIndex;
@@ -257,12 +257,11 @@ static void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args,
}
static void AnalyzeVarArgs(CCState &State,
- const SmallVectorImpl<ISD::OutputArg> &Outs) {
+ llvm::ArrayRef<ISD::OutputArg> Outs) {
State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack);
}
-static void AnalyzeVarArgs(CCState &State,
- const SmallVectorImpl<ISD::InputArg> &Ins) {
+static void AnalyzeVarArgs(CCState &State, llvm::ArrayRef<ISD::InputArg> Ins) {
State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack);
}
@@ -270,10 +269,10 @@ static void AnalyzeVarArgs(CCState &State,
/// to handle special constraints in the ABI like reversing the order of the
/// pieces of splitted arguments. In addition, all pieces of a certain argument
/// have to be passed either using registers or the stack but never mixing both.
-template<typename ArgT>
+template <typename ArgRangeT>
static void AnalyzeArguments(CCState &State,
SmallVectorImpl<CCValAssign> &ArgLocs,
- const SmallVectorImpl<ArgT> &Args) {
+ const ArgRangeT &Args) {
static const MCPhysReg CRegList[] = {
MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
};
@@ -369,26 +368,26 @@ static void AnalyzeArguments(CCState &State,
}
static void AnalyzeRetResult(CCState &State,
- const SmallVectorImpl<ISD::InputArg> &Ins) {
+ llvm::ArrayRef<ISD::InputArg> Ins) {
State.AnalyzeCallResult(Ins, RetCC_MSP430);
}
static void AnalyzeRetResult(CCState &State,
- const SmallVectorImpl<ISD::OutputArg> &Outs) {
+ llvm::ArrayRef<ISD::OutputArg> Outs) {
State.AnalyzeReturn(Outs, RetCC_MSP430);
}
-template<typename ArgT>
+template <typename ArgRangeT>
static void AnalyzeReturnValues(CCState &State,
SmallVectorImpl<CCValAssign> &RVLocs,
- const SmallVectorImpl<ArgT> &Args) {
+ const ArgRangeT &Args) {
AnalyzeRetResult(State, Args);
}
SDValue MSP430TargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
switch (CallConv) {
default:
@@ -408,17 +407,16 @@ MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &dl = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
- SDValue Callee = CLI.Callee;
- bool &isTailCall = CLI.IsTailCall;
+ SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool isVarArg = CLI.IsVarArg;
+ bool isVarArg = CLI.getIsVarArg();
// MSP430 target does not yet support tail call optimization.
- isTailCall = false;
+ CLI.setIsTailCall(false);
switch (CallConv) {
default:
@@ -426,8 +424,9 @@ MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
case CallingConv::MSP430_BUILTIN:
case CallingConv::Fast:
case CallingConv::C:
- return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
- Outs, OutVals, Ins, dl, DAG, InVals);
+ return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg,
+ CLI.getIsTailCall(), Outs, OutVals, Ins, dl, DAG,
+ InVals);
case CallingConv::MSP430_INTR:
report_fatal_error("ISRs cannot be called directly");
}
@@ -438,8 +437,8 @@ MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// FIXME: struct return stuff
SDValue MSP430TargetLowering::LowerCCCArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
@@ -541,13 +540,11 @@ SDValue MSP430TargetLowering::LowerCCCArguments(
return Chain;
}
-bool
-MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
- MachineFunction &MF,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- LLVMContext &Context,
- const Type *RetTy) const {
+bool MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, RetCC_MSP430);
@@ -556,7 +553,7 @@ MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
SDValue
MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const {
@@ -626,10 +623,10 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
SDValue MSP430TargetLowering::LowerCCCCallTo(
SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ bool isTailCall, llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
@@ -755,8 +752,8 @@ SDValue MSP430TargetLowering::LowerCCCCallTo(
///
SDValue MSP430TargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.h b/llvm/lib/Target/MSP430/MSP430ISelLowering.h
index 6e90569b0752e..05a3105b1d05d 100644
--- a/llvm/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.h
@@ -85,42 +85,38 @@ namespace llvm {
private:
SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isTailCall, llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerCCCArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue
LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
- bool CanLowerReturn(CallingConv::ID CallConv,
- MachineFunction &MF,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
+ bool IsVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp
index dc33afac69485..abd4dc9d31970 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.cpp
@@ -149,7 +149,7 @@ void MipsInstPrinter::printJumpOperand(const MCInst *MI, unsigned OpNo,
if (!Op.isImm())
return printOperand(MI, OpNo, STI, O);
- if (PrintBranchImmAsAddress)
+ if (getPrintBranchImmAsAddress())
markup(O, Markup::Immediate) << formatHex(Op.getImm());
else
markup(O, Markup::Immediate) << formatImm(Op.getImm());
@@ -163,7 +163,7 @@ void MipsInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
if (!Op.isImm())
return printOperand(MI, OpNo, STI, O);
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address + Op.getImm();
if (STI.hasFeature(Mips::FeatureMips32))
Target &= 0xffffffff;
diff --git a/llvm/lib/Target/Mips/MipsBranchExpansion.cpp b/llvm/lib/Target/Mips/MipsBranchExpansion.cpp
index 2460459a9b3be..27f643edf3102 100644
--- a/llvm/lib/Target/Mips/MipsBranchExpansion.cpp
+++ b/llvm/lib/Target/Mips/MipsBranchExpansion.cpp
@@ -80,6 +80,7 @@
#include "MipsMachineFunction.h"
#include "MipsSubtarget.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -160,10 +161,12 @@ class MipsBranchExpansion : public MachineFunctionPass {
const MipsInstrInfo *TII;
MachineFunction *MFp;
- SmallVector<MBBInfo, 16> MBBInfos;
- bool IsPIC;
+ llvm::SmallVectorWithFlags<MBBInfo, 16, 2> MBBInfos;
+ bool getIsPIC() const { return MBBInfos.getFlag(0); }
+ void setIsPIC(bool Value) { MBBInfos.setFlag(0, Value); }
MipsABIInfo ABI;
- bool ForceLongBranchFirstPass = false;
+ bool getForceLongBranchFirstPass() const { return MBBInfos.getFlag(1); }
+ void setForceLongBranchFirstPass(bool Value) { MBBInfos.setFlag(1, Value); }
};
} // end of anonymous namespace
@@ -408,7 +411,7 @@ void MipsBranchExpansion::expandToLongBranch(MBBInfo &I) {
MFp->insert(FallThroughMBB, LongBrMBB);
MBB->replaceSuccessor(TgtMBB, LongBrMBB);
- if (IsPIC) {
+ if (getIsPIC()) {
MachineBasicBlock *BalTgtMBB = MFp->CreateMachineBasicBlock(BB);
MFp->insert(FallThroughMBB, BalTgtMBB);
LongBrMBB->addSuccessor(BalTgtMBB);
@@ -876,10 +879,10 @@ bool MipsBranchExpansion::handlePossibleLongBranch() {
if ((Br != End) && Br->isBranch() && !Br->isIndirectBranch() &&
(Br->isConditionalBranch() ||
- (Br->isUnconditionalBranch() && IsPIC))) {
+ (Br->isUnconditionalBranch() && getIsPIC()))) {
int64_t Offset = computeOffset(&*Br);
- if (ForceLongBranchFirstPass ||
+ if (getForceLongBranchFirstPass() ||
!TII->isBranchOffsetInRange(Br->getOpcode(), Offset)) {
MBBInfos[I].Offset = Offset;
MBBInfos[I].Br = &*Br;
@@ -887,7 +890,7 @@ bool MipsBranchExpansion::handlePossibleLongBranch() {
}
} // End for
- ForceLongBranchFirstPass = false;
+ setForceLongBranchFirstPass(false);
SmallVectorImpl<MBBInfo>::iterator I, E = MBBInfos.end();
@@ -910,18 +913,18 @@ bool MipsBranchExpansion::handlePossibleLongBranch() {
bool MipsBranchExpansion::runOnMachineFunction(MachineFunction &MF) {
const TargetMachine &TM = MF.getTarget();
- IsPIC = TM.isPositionIndependent();
+ setIsPIC(TM.isPositionIndependent());
STI = &MF.getSubtarget<MipsSubtarget>();
ABI = STI->getABI();
TII = STI->getInstrInfo();
- if (IsPIC && ABI.IsO32() &&
+ if (getIsPIC() && ABI.IsO32() &&
MF.getInfo<MipsFunctionInfo>()->globalBaseRegSet())
emitGPDisp(MF, TII);
MFp = &MF;
- ForceLongBranchFirstPass = STI->getCLOpts().force_mips_long_branch;
+ setForceLongBranchFirstPass(STI->getCLOpts().force_mips_long_branch);
// Run these at least once.
bool longBranchChanged = handlePossibleLongBranch();
bool forbiddenSlotChanged = handleForbiddenSlot();
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index 98a8c563defbf..37078ecc1cf7e 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -420,7 +420,7 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
MachineInstrBuilder MIB = MIRBuilder.buildInstrNoInsert(
Info.Callee.isReg() || IsCalleeGlobalPIC ? Mips::JALRPseudo : Mips::JAL);
MIB.setOperandDead(0); // implicit-def $ra
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::MIFlag::NoMerge);
MIB.addDef(Mips::SP, RegState::Implicit);
if (IsCalleeGlobalPIC) {
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index b9c1c57af6e61..451417a4a0b97 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3385,14 +3385,13 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc DL = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
- SDValue Callee = CLI.Callee;
- bool &IsTailCall = CLI.IsTailCall;
+ SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
const CallBase *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
@@ -3471,9 +3470,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
CalleeIsLocal = GV->isDSOLocal();
}
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
if (!Subtarget.getCLOpts().tail_calls) {
- IsTailCall = false;
+ CLI.setIsTailCall(false);
if (IsMustTail)
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail");
@@ -3481,7 +3480,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
bool Eligible = isEligibleForTailCallOptimization(
CCInfo, StackSize, *MF.getInfo<MipsFunctionInfo>());
if (!Eligible || !CalleeIsLocal) {
- IsTailCall = false;
+ CLI.setIsTailCall(false);
if (IsMustTail)
report_fatal_error(
"failed to perform tail call elimination on a call "
@@ -3490,7 +3489,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
}
}
- if (IsTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
// Chain is the output chain of the last Load/Store or CopyToReg node.
@@ -3499,7 +3498,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
unsigned StackAlignment = TFL->getStackAlignment();
StackSize = alignTo(StackSize, StackAlignment);
- if (!(IsTailCall || MemcpyInByVal))
+ if (!(CLI.getIsTailCall() || MemcpyInByVal))
Chain = DAG.getCALLSEQ_START(Chain, StackSize, 0, DL);
SDValue StackPtr =
@@ -3527,7 +3526,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
assert(Flags.getByValSize() &&
"ByVal args of size 0 should have been ignored by front-end.");
assert(ByValIdx < CCInfo.getInRegsParamsCount());
- assert(!IsTailCall &&
+ assert(!CLI.getIsTailCall() &&
"Do not tail-call optimize if there is a byval argument.");
passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,
FirstByValReg, LastByValReg, Flags, Subtarget.isLittle(),
@@ -3618,8 +3617,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// emit ISD::STORE whichs stores the
// parameter value to a stack Location
- MemOpChains.push_back(passArgOnStack(StackPtr, VA.getLocMemOffset(),
- Chain, Arg, DL, IsTailCall, DAG));
+ MemOpChains.push_back(passArgOnStack(StackPtr, VA.getLocMemOffset(), Chain,
+ Arg, DL, CLI.getIsTailCall(), DAG));
}
// Transform all store nodes into one single node because all store
@@ -3720,7 +3719,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
getOpndList(Ops, RegsToPass, IsPIC, GlobalOrExternal, LocalLinkage,
IsCallReloc, CLI, Callee, Chain);
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
MF.getFrameInfo().setHasTailCall();
SDValue Ret = DAG.getNode(MipsISD::TailCall, DL, MVT::Other, Ops);
DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
@@ -3749,8 +3748,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
/// appropriate copies out of appropriate physical registers.
SDValue MipsTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals,
TargetLowering::CallLoweringInfo &CLI) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
@@ -3873,8 +3872,8 @@ static SDValue UnpackFromArgumentSlot(SDValue Val, const CCValAssign &VA,
/// and generate load operations for arguments places on the stack.
SDValue MipsTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
@@ -4028,11 +4027,11 @@ SDValue MipsTargetLowering::LowerFormalArguments(
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
-bool
-MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
- MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- LLVMContext &Context, const Type *RetTy) const {
+bool MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, RetCC_Mips);
@@ -4058,12 +4057,12 @@ MipsTargetLowering::LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,
return DAG.getNode(MipsISD::ERet, DL, MVT::Other, RetOps);
}
-SDValue
-MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &DL, SelectionDAG &DAG) const {
+SDValue MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL,
+ SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of
// the return value to a location
SmallVector<CCValAssign, 16> RVLocs;
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 84af86e6cc088..42a13cbca2006 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -347,9 +347,8 @@ using TargetRegisterClass = MCRegisterClass;
// Lower Operand helpers
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
TargetLowering::CallLoweringInfo &CLI) const;
// Lower Operand specifics
@@ -420,8 +419,8 @@ using TargetRegisterClass = MCRegisterClass;
SDValue
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain,
@@ -432,12 +431,11 @@ using TargetRegisterClass = MCRegisterClass;
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
index ca39b74b244d3..b618aad74c169 100644
--- a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
+++ b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.cpp
@@ -36,7 +36,7 @@ void NVPTXTargetStreamer::outputDwarfFileDirectives() {
}
void NVPTXTargetStreamer::closeLastSection() {
- if (HasSections)
+ if (getHasSections())
getStreamer().emitRawText("\t}");
}
@@ -98,7 +98,7 @@ void NVPTXTargetStreamer::changeSection(const MCSection *CurSection,
OS << "\t.section\t" << Section->getName() << '\n';
// DWARF sections are enclosed into braces - emit the open one.
OS << "\t{\n";
- HasSections = true;
+ setHasSections(true);
}
}
diff --git a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h
index cad8c7dc19263..acd4f7d89fd07 100644
--- a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h
+++ b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXTargetStreamer.h
@@ -10,6 +10,7 @@
#define LLVM_LIB_TARGET_NVPTX_MCTARGETDESC_NVPTXTARGETSTREAMER_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/MC/MCStreamer.h"
#include <optional>
@@ -21,8 +22,9 @@ class formatted_raw_ostream;
/// Implments NVPTX-specific streamer.
class NVPTXTargetStreamer : public MCTargetStreamer {
private:
- SmallVector<std::string, 4> DwarfFiles;
- bool HasSections = false;
+ llvm::SmallVectorWithFlags<std::string, 4> DwarfFiles;
+ bool getHasSections() const { return DwarfFiles.getFlag(0); }
+ void setHasSections(bool Value) { DwarfFiles.setFlag(0, Value); }
public:
NVPTXTargetStreamer(MCStreamer &S);
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index ab90036722ca4..60bf3de0fe0bb 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -37,6 +37,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -162,15 +163,18 @@ class NVPTXAsmPrinter : public AsmPrinter {
// We need to keep these values because AggBuffer::print decides whether to
// emit a "generic()" cast for Symbols[i] depending on the address space of
// SymbolsBeforeStripping[i].
- SmallVector<const Value *, 4> SymbolsBeforeStripping;
+ llvm::SmallVectorWithFlags<const Value *, 4> SymbolsBeforeStripping;
unsigned curpos;
const NVPTXAsmPrinter &AP;
- const bool EmitGeneric;
+ bool getEmitGeneric() const { return SymbolsBeforeStripping.getFlag(0); }
public:
AggBuffer(unsigned Size, const NVPTXAsmPrinter &AP)
- : Size(Size), buffer(Size), curpos(0), AP(AP),
- EmitGeneric(AP.EmitGeneric) {}
+ : Size(Size), buffer(Size),
+ SymbolsBeforeStripping(
+ decltype(this->SymbolsBeforeStripping)::withFlags(
+ unsigned(bool(AP.EmitGeneric)))),
+ curpos(0), AP(AP) {}
unsigned getBufferSize() const { return Size; }
@@ -1593,7 +1597,7 @@ void NVPTXAsmPrinter::AggBuffer::printSymbol(unsigned nSym, raw_ostream &os) {
PointerType *PTy = dyn_cast<PointerType>(v0->getType());
// Is v0 a generic pointer?
bool isGenericPointer = PTy && PTy->getAddressSpace() == 0;
- if (EmitGeneric && isGenericPointer && !isa<Function>(v)) {
+ if (getEmitGeneric() && isGenericPointer && !isa<Function>(v)) {
os << "generic(";
Name->print(os, AP.MAI);
os << ")";
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
index 7d55ba810e106..037813739c962 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -1298,7 +1298,7 @@ static SDValue getSymbolNode(SelectionDAG &DAG, const Twine &Name, EVT T) {
SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
- if (CLI.IsVarArg &&
+ if (CLI.getIsVarArg() &&
(!STI.hasFeature(NVPTX::PTX60) || !STI.hasFeature(NVPTX::SM30)))
report_fatal_error(
"Support for variadic functions (unsized array parameter) introduced "
@@ -1306,7 +1306,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SelectionDAG &DAG = CLI.DAG;
SDLoc dl = CLI.DL;
- const SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ const auto &Ins = CLI.Ins;
SDValue Callee = CLI.Callee;
ArgListTy &Args = CLI.getArgs();
Type *RetTy = CLI.RetTy;
@@ -1363,7 +1363,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
//
// After all vararg is processed, 'VAOffset' holds the size of the
// vararg byte array.
- assert((CLI.IsVarArg || CLI.Args.size() <= CLI.NumFixedArgs) &&
+ assert((CLI.getIsVarArg() || CLI.Args.size() <= CLI.NumFixedArgs) &&
"Non-VarArg function with extra arguments");
const unsigned FirstVAArg = CLI.NumFixedArgs; // position of first variadic
@@ -1636,7 +1636,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
const SDValue CallToken = DAG.getTokenFactor(dl, CallPrereqs);
const SDValue Call = DAG.getNode(
NVPTXISD::CALL, dl, MVT::Other,
- {CallToken, GetI32(CLI.IsConvergent), GetI32(IsIndirectCall),
+ {CallToken, GetI32(CLI.getIsConvergent()), GetI32(IsIndirectCall),
GetI32(Ins.empty() ? 0 : 1), GetI32(NumArgs), Callee, Proto});
SmallVector<SDValue, 16> LoadChains{Call};
@@ -1698,7 +1698,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// set IsTailCall to false for now, until we figure out how to express
// tail call optimization in PTX
- CLI.IsTailCall = false;
+ CLI.setIsTailCall(false);
return CallEnd;
}
@@ -4276,8 +4276,8 @@ SDValue NVPTXTargetLowering::getCallParamSymbolNode(SelectionDAG &DAG, int I,
SDValue NVPTXTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
const DataLayout &DL = DAG.getDataLayout();
LLVMContext &Ctx = *DAG.getContext();
@@ -4405,7 +4405,7 @@ SDValue NVPTXTargetLowering::LowerFormalArguments(
SDValue
NVPTXTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const {
const Function &F = DAG.getMachineFunction().getFunction();
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.h b/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
index 4942408f6449b..7b8590e0f80c1 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.h
@@ -73,8 +73,7 @@ class NVPTXTargetLowering : public TargetLowering {
StringRef Constraint, MVT VT) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
@@ -86,7 +85,7 @@ class NVPTXTargetLowering : public TargetLowering {
SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp b/llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp
index 45dbd50945bfe..c49e2e75ced75 100644
--- a/llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXLowerArgs.cpp
@@ -185,7 +185,7 @@ struct ArgUseChecker : PtrUseVisitor<ArgUseChecker> {
PtrInfo visitArgPtr(Argument &A) {
assert(A.getType()->isPointerTy());
IntegerType *IntIdxTy = cast<IntegerType>(DL.getIndexType(A.getType()));
- IsOffsetKnown = false;
+ setIsOffsetKnown(false);
Offset = APInt(IntIdxTy->getBitWidth(), 0);
PI.reset();
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index 3f455223f401d..badb107f043e7 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -422,7 +422,7 @@ void PPCInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
if (!MI->getOperand(OpNo).isImm())
return printOperand(MI, OpNo, STI, O);
int32_t Imm = SignExtend32<32>((unsigned)MI->getOperand(OpNo).getImm() << 2);
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address + Imm;
if (!TT.isPPC64())
Target &= 0xffffffff;
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index e2e3d0f70d0e1..674e410805a5a 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -2462,7 +2462,7 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
- const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
+ ArrayRef<Register> MustSaveCRs = FI->getMustSaveCRs();
if (!MustSaveCRs.empty())
FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask;
diff --git a/llvm/lib/Target/PowerPC/PPCBranchCoalescing.cpp b/llvm/lib/Target/PowerPC/PPCBranchCoalescing.cpp
index 3644e75609fc3..53aec13cec236 100644
--- a/llvm/lib/Target/PowerPC/PPCBranchCoalescing.cpp
+++ b/llvm/lib/Target/PowerPC/PPCBranchCoalescing.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "PPC.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -137,9 +138,11 @@ class PPCBranchCoalescing : public MachineFunctionPass {
MachineBasicBlock *BranchBlock; // Block containing the branch
MachineBasicBlock *BranchTargetBlock; // Block branched to
MachineBasicBlock *FallThroughBlock; // Fall-through if branch not taken
- SmallVector<MachineOperand, 4> Cond;
- bool MustMoveDown;
- bool MustMoveUp;
+ llvm::SmallVectorWithFlags<MachineOperand, 4, 2> Cond;
+ bool getMustMoveDown() const { return Cond.getFlag(0); }
+ void setMustMoveDown(bool Value) { Cond.setFlag(0, Value); }
+ bool getMustMoveUp() const { return Cond.getFlag(1); }
+ void setMustMoveUp(bool Value) { Cond.setFlag(1, Value); }
CoalescingCandidateInfo();
void clear();
@@ -200,15 +203,15 @@ INITIALIZE_PASS_END(PPCBranchCoalescing, DEBUG_TYPE, "Branch Coalescing",
PPCBranchCoalescing::CoalescingCandidateInfo::CoalescingCandidateInfo()
: BranchBlock(nullptr), BranchTargetBlock(nullptr),
- FallThroughBlock(nullptr), MustMoveDown(false), MustMoveUp(false) {}
+ FallThroughBlock(nullptr) {}
void PPCBranchCoalescing::CoalescingCandidateInfo::clear() {
BranchBlock = nullptr;
BranchTargetBlock = nullptr;
FallThroughBlock = nullptr;
Cond.clear();
- MustMoveDown = false;
- MustMoveUp = false;
+ setMustMoveDown(false);
+ setMustMoveUp(false);
}
void PPCBranchCoalescing::initialize(MachineFunction &MF) {
@@ -233,8 +236,12 @@ bool PPCBranchCoalescing::canCoalesceBranch(CoalescingCandidateInfo &Cand) {
<< Cand.BranchBlock->getNumber() << " can be coalesced:");
MachineBasicBlock *FalseMBB = nullptr;
- if (TII->analyzeBranch(*Cand.BranchBlock, Cand.BranchTargetBlock, FalseMBB,
- Cand.Cond)) {
+ SmallVector<MachineOperand, 4> Condition;
+ Condition = std::move(Cand.Cond);
+ bool CannotAnalyze = TII->analyzeBranch(
+ *Cand.BranchBlock, Cand.BranchTargetBlock, FalseMBB, Condition);
+ Cand.Cond.assign(std::move(Condition));
+ if (CannotAnalyze) {
LLVM_DEBUG(dbgs() << "TII unable to Analyze Branch - skip\n");
return false;
}
@@ -551,7 +558,7 @@ bool PPCBranchCoalescing::canMerge(CoalescingCandidateInfo &SourceRegion,
LLVM_DEBUG(dbgs() << "PHI " << *I
<< " defines register used in this "
"block -- all must move down\n");
- SourceRegion.MustMoveDown = true;
+ SourceRegion.setMustMoveDown(true);
}
}
}
@@ -565,16 +572,18 @@ bool PPCBranchCoalescing::canMerge(CoalescingCandidateInfo &SourceRegion,
if (!canMoveToBeginning(*I, *SourceRegion.BranchTargetBlock)) {
LLVM_DEBUG(dbgs() << "Instruction " << *I
<< " cannot move down - must move up!\n");
- SourceRegion.MustMoveUp = true;
+ SourceRegion.setMustMoveUp(true);
}
if (!canMoveToEnd(*I, *TargetRegion.BranchBlock)) {
LLVM_DEBUG(dbgs() << "Instruction " << *I
<< " cannot move up - must move down!\n");
- SourceRegion.MustMoveDown = true;
+ SourceRegion.setMustMoveDown(true);
}
}
- return (SourceRegion.MustMoveUp && SourceRegion.MustMoveDown) ? false : true;
+ return (SourceRegion.getMustMoveUp() && SourceRegion.getMustMoveDown())
+ ? false
+ : true;
}
/// Merge the instructions from SourceRegion.BranchBlock,
@@ -636,7 +645,7 @@ bool PPCBranchCoalescing::canMerge(CoalescingCandidateInfo &SourceRegion,
bool PPCBranchCoalescing::mergeCandidates(CoalescingCandidateInfo &SourceRegion,
CoalescingCandidateInfo &TargetRegion) {
- if (SourceRegion.MustMoveUp && SourceRegion.MustMoveDown) {
+ if (SourceRegion.getMustMoveUp() && SourceRegion.getMustMoveDown()) {
llvm_unreachable("Cannot have both MustMoveDown and MustMoveUp set!");
return false;
}
@@ -655,12 +664,12 @@ bool PPCBranchCoalescing::mergeCandidates(CoalescingCandidateInfo &SourceRegion,
MachineBasicBlock::iterator lastInstr =
SourceRegion.BranchBlock->getFirstTerminator();
- MachineBasicBlock *Source = SourceRegion.MustMoveDown
+ MachineBasicBlock *Source = SourceRegion.getMustMoveDown()
? SourceRegion.BranchTargetBlock
: TargetRegion.BranchBlock;
MachineBasicBlock::iterator Target =
- SourceRegion.MustMoveDown
+ SourceRegion.getMustMoveDown()
? SourceRegion.BranchTargetBlock->getFirstNonPHI()
: TargetRegion.BranchBlock->getFirstTerminator();
diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index 6d8300fc8faa2..93e2761477765 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -639,7 +639,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
bool MustSaveLR = FI->mustSaveLR();
bool MustSaveTOC = FI->mustSaveTOC();
- const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
+ ArrayRef<Register> MustSaveCRs = FI->getMustSaveCRs();
bool MustSaveCR = !MustSaveCRs.empty();
// Do we have a frame pointer and/or base pointer for this function?
bool HasFP = hasFP(MF);
@@ -1561,7 +1561,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
// Check if the link register (LR) has been saved.
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
bool MustSaveLR = FI->mustSaveLR();
- const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
+ ArrayRef<Register> MustSaveCRs = FI->getMustSaveCRs();
bool MustSaveCR = !MustSaveCRs.empty();
// Do we have a frame pointer and/or base pointer for this function?
bool HasFP = hasFP(MF);
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 43258d8ff0b87..4cd2f14d87d5e 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -24,6 +24,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
@@ -1856,7 +1857,7 @@ class BitPermutationSelector {
// For each value (except the constant ones), compute the left-rotate amount
// to get it from its original to final position.
void computeRotationAmounts() {
- NeedMask = false;
+ setNeedMask(false);
RLAmt.resize(Bits.size());
for (unsigned i = 0; i < Bits.size(); ++i)
if (Bits[i].hasValue()) {
@@ -1866,7 +1867,7 @@ class BitPermutationSelector {
else
RLAmt[i] = Bits.size() - (VBI - i);
} else if (Bits[i].isZero()) {
- NeedMask = true;
+ setNeedMask(true);
RLAmt[i] = UINT32_MAX;
} else {
llvm_unreachable("Unknown value bit type");
@@ -2276,7 +2277,7 @@ class BitPermutationSelector {
// If we've not yet selected a 'starting' instruction, and we have no zeros
// to fill in, select the (Value, RLAmt) with the highest priority (largest
// number of groups), and start with this rotated value.
- if ((!NeedMask || LateMask) && !Res) {
+ if ((!getNeedMask() || LateMask) && !Res) {
ValueRotInfo &VRI = ValueRotsVec[0];
if (VRI.RLAmt) {
if (InstCnt) *InstCnt += 1;
@@ -2662,7 +2663,7 @@ class BitPermutationSelector {
// If we've not yet selected a 'starting' instruction, and we have no zeros
// to fill in, select the (Value, RLAmt) with the highest priority (largest
// number of groups), and start with this rotated value.
- if ((!NeedMask || LateMask) && !Res) {
+ if ((!getNeedMask() || LateMask) && !Res) {
// If we have both Repl32 groups and non-Repl32 groups, the non-Repl32
// groups will come first, and so the VRI representing the largest number
// of groups might not be first (it might be the first Repl32 groups).
@@ -2822,13 +2823,14 @@ class BitPermutationSelector {
SmallVector<ValueBit, 64> Bits;
- bool NeedMask = false;
+ bool getNeedMask() const { return ValueRotsVec.getFlag(0); }
+ void setNeedMask(bool Value) { ValueRotsVec.setFlag(0, Value); }
SmallVector<unsigned, 64> RLAmt;
SmallVector<BitGroup, 16> BitGroups;
DenseMap<std::pair<SDValue, unsigned>, ValueRotInfo> ValueRots;
- SmallVector<ValueRotInfo, 16> ValueRotsVec;
+ llvm::SmallVectorWithFlags<ValueRotInfo, 16> ValueRotsVec;
SelectionDAG *CurDAG = nullptr;
@@ -2854,7 +2856,7 @@ class BitPermutationSelector {
// Fill it RLAmt and set NeedMask.
computeRotationAmounts();
- if (!NeedMask)
+ if (!getNeedMask())
return Select(N, false);
// We currently have two techniques for handling results with zeros: early
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index b2f1fd6176862..af896c7f5e875 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -4191,8 +4191,8 @@ static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering,
SDValue PPCTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
if (Subtarget.isAIXABI())
return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
InVals);
@@ -4206,8 +4206,8 @@ SDValue PPCTargetLowering::LowerFormalArguments(
SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// 32-bit SVR4 ABI Stack Frame Layout:
// +-----------------------------------+
@@ -4464,8 +4464,8 @@ SDValue PPCTargetLowering::extendArgForPPC64(ISD::ArgFlagsTy Flags,
SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// TODO: add description of PPC stack frame format, or at least some docs.
//
bool isELFv2ABI = Subtarget.isELFv2ABI();
@@ -4934,9 +4934,8 @@ static bool callsShareTOCBase(const Function *Caller,
return true;
}
-static bool
-needStackSlotPassParameters(const PPCSubtarget &Subtarget,
- const SmallVectorImpl<ISD::OutputArg> &Outs) {
+static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget,
+ llvm::ArrayRef<ISD::OutputArg> Outs) {
assert(Subtarget.is64BitELFABI());
const unsigned PtrByteSize = 8;
@@ -5021,9 +5020,8 @@ areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC,
bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
CallingConv::ID CallerCC, const CallBase *CB, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<ISD::InputArg> &Ins, const Function *CallerFunc,
- bool isCalleeExternalSymbol) const {
+ llvm::ArrayRef<ISD::OutputArg> Outs, llvm::ArrayRef<ISD::InputArg> Ins,
+ const Function *CallerFunc, bool isCalleeExternalSymbol) const {
bool TailCallOpt = getTargetMachine().Options.GuaranteedTailCallOpt;
if (!EnableSCO && !TailCallOpt)
@@ -5110,7 +5108,7 @@ bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
bool PPCTargetLowering::IsEligibleForTailCallOptimization(
const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
CallingConv::ID CallerCC, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins) const {
+ llvm::ArrayRef<ISD::InputArg> Ins) const {
if (!getTargetMachine().Options.GuaranteedTailCallOpt)
return false;
@@ -5319,8 +5317,8 @@ static bool isFunctionGlobalAddress(const GlobalValue *GV) {
SDValue PPCTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCRetInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
*DAG.getContext());
@@ -5785,7 +5783,7 @@ SDValue PPCTargetLowering::FinishCall(
CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG,
SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass, SDValue Glue,
SDValue Chain, SDValue CallSeqStart, SDValue &Callee, int SPDiff,
- unsigned NumBytes, const SmallVectorImpl<ISD::InputArg> &Ins,
+ unsigned NumBytes, llvm::ArrayRef<ISD::InputArg> Ins,
SmallVectorImpl<SDValue> &InVals, const CallBase *CB) const {
if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
@@ -5884,9 +5882,8 @@ bool PPCTargetLowering::supportsTailCallFor(const CallBase *CB) const {
bool PPCTargetLowering::isEligibleForTCO(
const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
CallingConv::ID CallerCC, const CallBase *CB, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<ISD::InputArg> &Ins, const Function *CallerFunc,
- bool isCalleeExternalSymbol) const {
+ llvm::ArrayRef<ISD::OutputArg> Outs, llvm::ArrayRef<ISD::InputArg> Ins,
+ const Function *CallerFunc, bool isCalleeExternalSymbol) const {
if (Subtarget.useLongCalls() && !(CB && CB->isMustTailCall()))
return false;
@@ -5904,28 +5901,27 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &dl = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
- SDValue Callee = CLI.Callee;
- bool &isTailCall = CLI.IsTailCall;
+ SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool isVarArg = CLI.IsVarArg;
- bool isPatchPoint = CLI.IsPatchPoint;
+ bool isVarArg = CLI.getIsVarArg();
+ bool isPatchPoint = CLI.getIsPatchPointFlag();
const CallBase *CB = CLI.CB;
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
MachineFunction &MF = DAG.getMachineFunction();
CallingConv::ID CallerCC = MF.getFunction().getCallingConv();
auto *G = dyn_cast<GlobalAddressSDNode>(Callee);
const GlobalValue *GV = G ? G->getGlobal() : nullptr;
bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
- isTailCall =
- isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
- &(MF.getFunction()), IsCalleeExternalSymbol);
- if (isTailCall) {
+ CLI.setIsTailCall(isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg,
+ Outs, Ins, &(MF.getFunction()),
+ IsCalleeExternalSymbol));
+ if (CLI.getIsTailCall()) {
++NumTailCalls;
if (!getTargetMachine().Options.GuaranteedTailCallOpt)
++NumSiblingCalls;
@@ -5946,7 +5942,7 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
}
}
- if (!isTailCall && CB && CB->isMustTailCall())
+ if (!CLI.getIsTailCall() && CB && CB->isMustTailCall())
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail");
@@ -5954,16 +5950,16 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// made via function pointer. If we have a function name, first translate it
// into a pointer.
if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
- !isTailCall)
+ !CLI.getIsTailCall())
Callee = LowerGlobalAddress(Callee, DAG);
CallFlags CFlags(
- CallConv, isTailCall, isVarArg, isPatchPoint,
+ CallConv, CLI.getIsTailCall(), isVarArg, isPatchPoint,
isIndirectCall(Callee, DAG, Subtarget, isPatchPoint),
// hasNest
Subtarget.is64BitELFABI() &&
any_of(Outs, [](ISD::OutputArg Arg) { return Arg.Flags.isNest(); }),
- CLI.NoMerge);
+ CLI.getNoMerge());
if (Subtarget.isAIXABI())
return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
@@ -5979,10 +5975,9 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SDValue PPCTargetLowering::LowerCall_32SVR4(
SDValue Chain, SDValue Callee, CallFlags CFlags,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
const CallBase *CB) const {
// See PPCTargetLowering::LowerFormalArguments_32SVR4() for a description
// of the 32-bit SVR4 ABI stack frame layout.
@@ -6229,10 +6224,9 @@ SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
SDValue PPCTargetLowering::LowerCall_64SVR4(
SDValue Chain, SDValue Callee, CallFlags CFlags,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
const CallBase *CB) const {
bool isELFv2ABI = Subtarget.isELFv2ABI();
bool isLittleEndian = Subtarget.isLittleEndian();
@@ -7195,8 +7189,8 @@ static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL) {
SDValue PPCTargetLowering::LowerFormalArguments_AIX(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
assert((CallConv == CallingConv::C || CallConv == CallingConv::Cold ||
CallConv == CallingConv::Fast) &&
@@ -7565,10 +7559,9 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
SDValue PPCTargetLowering::LowerCall_AIX(
SDValue Chain, SDValue Callee, CallFlags CFlags,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
const CallBase *CB) const {
// See PPCTargetLowering::LowerFormalArguments_AIX() for a description of the
// AIX ABI stack frame layout.
@@ -7886,12 +7879,11 @@ SDValue PPCTargetLowering::LowerCall_AIX(
Callee, SPDiff, NumBytes, Ins, InVals, CB);
}
-bool
-PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
- MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- LLVMContext &Context,
- const Type *RetTy) const {
+bool PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(
@@ -7900,12 +7892,12 @@ PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
: RetCC_PPC);
}
-SDValue
-PPCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &dl, SelectionDAG &DAG) const {
+SDValue PPCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &dl,
+ SelectionDAG &DAG) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
*DAG.getContext());
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index eaa27ee4e4229..1965f36c8c7e3 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -670,23 +670,22 @@ namespace llvm {
SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const;
SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const;
- bool IsEligibleForTailCallOptimization(
- const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
- CallingConv::ID CallerCC, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins) const;
+ bool
+ IsEligibleForTailCallOptimization(const GlobalValue *CalleeGV,
+ CallingConv::ID CalleeCC,
+ CallingConv::ID CallerCC, bool isVarArg,
+ llvm::ArrayRef<ISD::InputArg> Ins) const;
bool IsEligibleForTailCallOptimization_64SVR4(
const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
CallingConv::ID CallerCC, const CallBase *CB, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<ISD::InputArg> &Ins, const Function *CallerFunc,
- bool isCalleeExternalSymbol) const;
+ llvm::ArrayRef<ISD::OutputArg> Outs, llvm::ArrayRef<ISD::InputArg> Ins,
+ const Function *CallerFunc, bool isCalleeExternalSymbol) const;
bool isEligibleForTCO(const GlobalValue *CalleeGV, CallingConv::ID CalleeCC,
CallingConv::ID CallerCC, const CallBase *CB,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
+ llvm::ArrayRef<ISD::InputArg> Ins,
const Function *CallerFunc,
bool isCalleeExternalSymbol) const;
@@ -788,34 +787,33 @@ namespace llvm {
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue FinishCall(CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG,
SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
SDValue InGlue, SDValue Chain, SDValue CallSeqStart,
SDValue &Callee, int SPDiff, unsigned NumBytes,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ llvm::ArrayRef<ISD::InputArg> Ins,
SmallVectorImpl<SDValue> &InVals,
const CallBase *CB) const;
SDValue
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const override;
@@ -823,18 +821,21 @@ namespace llvm {
SelectionDAG &DAG, SDValue ArgVal,
const SDLoc &dl) const;
- SDValue LowerFormalArguments_AIX(
- SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;
- SDValue LowerFormalArguments_64SVR4(
- SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;
- SDValue LowerFormalArguments_32SVR4(
- SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;
+ SDValue LowerFormalArguments_AIX(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const;
+ SDValue LowerFormalArguments_64SVR4(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const;
+ SDValue LowerFormalArguments_32SVR4(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const;
SDValue createMemcpyOutsideCallSeq(SDValue Arg, SDValue PtrOff,
SDValue CallSeqStart,
@@ -842,25 +843,24 @@ namespace llvm {
const SDLoc &dl) const;
SDValue LowerCall_64SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals,
const CallBase *CB) const;
SDValue LowerCall_32SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals,
const CallBase *CB) const;
SDValue LowerCall_AIX(SDValue Chain, SDValue Callee, CallFlags CFlags,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
const CallBase *CB) const;
SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index b7d14da05ee24..c5269cb8e5f6e 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -14,6 +14,7 @@
#define LLVM_LIB_TARGET_POWERPC_PPCMACHINEFUNCTIONINFO_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetCallingConv.h"
@@ -91,7 +92,8 @@ class PPCFunctionInfo : public MachineFunctionInfo {
bool LRStoreRequired = false;
/// This function makes use of the PPC64 ELF TOC base pointer (register r2).
- bool UsesTOCBasePtr = false;
+ bool getUsesTOCBasePtrFlag() const { return MustSaveCRs.getFlag(0); }
+ void setUsesTOCBasePtrFlag(bool Value) { MustSaveCRs.setFlag(0, Value); }
/// MinReservedArea - This is the frame size that is at least reserved in a
/// potential caller (parameter+linkage area).
@@ -104,7 +106,8 @@ class PPCFunctionInfo : public MachineFunctionInfo {
/// HasFastCall - Does this function contain a fast call. Used to determine
/// how the caller's stack pointer should be calculated (epilog/dynamicalloc).
- bool HasFastCall = false;
+ bool getHasFastCallFlag() const { return MustSaveCRs.getFlag(1); }
+ void setHasFastCallFlag(bool Value) { MustSaveCRs.setFlag(1, Value); }
/// VarArgsFrameIndex - FrameIndex for start of varargs area.
int VarArgsFrameIndex = 0;
@@ -133,7 +136,7 @@ class PPCFunctionInfo : public MachineFunctionInfo {
/// ParamtersType - Store all the parameter's type that are saved on
/// registers.
- SmallVector<ParamType, 32> ParamtersType;
+ llvm::SmallVectorWithFlags<ParamType, 32> ParamtersType;
/// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
int CRSpillFrameIndex = 0;
@@ -141,10 +144,11 @@ class PPCFunctionInfo : public MachineFunctionInfo {
/// If any of CR[2-4] need to be saved in the prologue and restored in the
/// epilogue then they are added to this array. This is used for the
/// 64-bit SVR4 ABI.
- SmallVector<Register, 3> MustSaveCRs;
+ llvm::SmallVectorWithFlags<Register, 3, 4> MustSaveCRs;
/// Whether this uses the PIC Base register or not.
- bool UsesPICBase = false;
+ bool getUsesPICBaseFlag() const { return MustSaveCRs.getFlag(2); }
+ void setUsesPICBaseFlag(bool Value) { MustSaveCRs.setFlag(2, Value); }
/// We keep track attributes for each live-in virtual registers
/// to use SExt/ZExt flags in later optimization.
@@ -152,8 +156,16 @@ class PPCFunctionInfo : public MachineFunctionInfo {
/// Flags for aix-shared-lib-tls-model-opt, will be lazily initialized for
/// each function.
- bool AIXFuncUseTLSIEForLD = false;
- bool AIXFuncTLSModelOptInitDone = false;
+ bool getAIXFuncUseTLSIEForLDFlag() const { return MustSaveCRs.getFlag(3); }
+ void setAIXFuncUseTLSIEForLDFlag(bool Value) {
+ MustSaveCRs.setFlag(3, Value);
+ }
+ bool getAIXFuncTLSModelOptInitDoneFlag() const {
+ return ParamtersType.getFlag(0);
+ }
+ void setAIXFuncTLSModelOptInitDoneFlag(bool Value) {
+ ParamtersType.setFlag(0, Value);
+ }
public:
explicit PPCFunctionInfo(const Function &F, const TargetSubtargetInfo *STI);
@@ -220,18 +232,20 @@ class PPCFunctionInfo : public MachineFunctionInfo {
void setLRStoreRequired() { LRStoreRequired = true; }
bool isLRStoreRequired() const { return LRStoreRequired; }
- void setUsesTOCBasePtr() { UsesTOCBasePtr = true; }
- bool usesTOCBasePtr() const { return UsesTOCBasePtr; }
+ void setUsesTOCBasePtr() { setUsesTOCBasePtrFlag(true); }
+ bool usesTOCBasePtr() const { return getUsesTOCBasePtrFlag(); }
- void setHasFastCall() { HasFastCall = true; }
- bool hasFastCall() const { return HasFastCall;}
+ void setHasFastCall() { setHasFastCallFlag(true); }
+ bool hasFastCall() const { return getHasFastCallFlag(); }
- void setAIXFuncTLSModelOptInitDone() { AIXFuncTLSModelOptInitDone = true; }
+ void setAIXFuncTLSModelOptInitDone() {
+ setAIXFuncTLSModelOptInitDoneFlag(true);
+ }
bool isAIXFuncTLSModelOptInitDone() const {
- return AIXFuncTLSModelOptInitDone;
+ return getAIXFuncTLSModelOptInitDoneFlag();
}
- void setAIXFuncUseTLSIEForLD() { AIXFuncUseTLSIEForLD = true; }
- bool isAIXFuncUseTLSIEForLD() const { return AIXFuncUseTLSIEForLD; }
+ void setAIXFuncUseTLSIEForLD() { setAIXFuncUseTLSIEForLDFlag(true); }
+ bool isAIXFuncUseTLSIEForLD() const { return getAIXFuncUseTLSIEForLDFlag(); }
int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
@@ -272,12 +286,11 @@ class PPCFunctionInfo : public MachineFunctionInfo {
int getCRSpillFrameIndex() const { return CRSpillFrameIndex; }
void setCRSpillFrameIndex(int idx) { CRSpillFrameIndex = idx; }
- const SmallVectorImpl<Register> &
- getMustSaveCRs() const { return MustSaveCRs; }
+ ArrayRef<Register> getMustSaveCRs() const { return MustSaveCRs; }
void addMustSaveCR(Register Reg) { MustSaveCRs.push_back(Reg); }
- void setUsesPICBase(bool uses) { UsesPICBase = uses; }
- bool usesPICBase() const { return UsesPICBase; }
+ void setUsesPICBase(bool uses) { setUsesPICBaseFlag(uses); }
+ bool usesPICBase() const { return getUsesPICBaseFlag(); }
MCSymbol *getPICOffsetSymbol(MachineFunction &MF) const;
diff --git a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
index b7ad26081ea4d..6946d8ad83cc7 100644
--- a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
@@ -1005,8 +1005,8 @@ bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
case Intrinsic::ppc_vsx_lxvll:
case Intrinsic::ppc_vsx_lxvp: {
Info.PtrVal = Inst->getArgOperand(0);
- Info.ReadMem = true;
- Info.WriteMem = false;
+ Info.setReadMem(true);
+ Info.setWriteMem(false);
return true;
}
case Intrinsic::ppc_altivec_stvx:
@@ -1022,8 +1022,8 @@ bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
case Intrinsic::ppc_vsx_stxvll:
case Intrinsic::ppc_vsx_stxvp: {
Info.PtrVal = Inst->getArgOperand(1);
- Info.ReadMem = false;
- Info.WriteMem = true;
+ Info.setReadMem(false);
+ Info.setWriteMem(true);
return true;
}
case Intrinsic::ppc_stbcx:
@@ -1031,8 +1031,8 @@ bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
case Intrinsic::ppc_stdcx:
case Intrinsic::ppc_stwcx: {
Info.PtrVal = Inst->getArgOperand(0);
- Info.ReadMem = false;
- Info.WriteMem = true;
+ Info.setReadMem(false);
+ Info.setWriteMem(true);
return true;
}
default:
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
index 07029d09dad7c..5a77ff4a5d8e0 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
@@ -624,7 +624,7 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
.buildInstrNoInsert(Info.Callee.isReg() ? RISCV::PseudoCALLIndirect
: RISCV::PseudoCALL)
.add(Info.Callee);
- if (Info.NoMerge)
+ if (Info.getNoMerge())
Call.setMIFlag(MachineInstr::MIFlag::NoMerge);
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
Call.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv))
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index 222b7cae942c8..cec3980efb358 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -108,14 +108,14 @@ void RISCVInstPrinter::printBranchOperand(const MCInst *MI, uint64_t Address,
const MCSubtargetInfo &STI,
raw_ostream &O) {
// Do not print the numeric target address when symbolizing.
- if (SymbolizeOperands)
+ if (getSymbolizeOperands())
return;
const MCOperand &MO = MI->getOperand(OpNo);
if (!MO.isImm())
return printOperand(MI, OpNo, STI, O);
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address + MO.getImm();
if (!STI.hasFeature(RISCV::Feature64Bit))
Target &= 0xffffffff;
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 17032ffc99a7b..e71f163a1a0bb 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -28062,8 +28062,8 @@ static SDValue unpackGPRVecOnRV32(SelectionDAG &DAG, SDValue Chain,
// Transform physical registers into virtual registers.
SDValue RISCVTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
@@ -28376,14 +28376,13 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
- bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
EVT PtrVT = getPointerTy(DAG.getDataLayout());
MVT XLenVT = Subtarget.getXLenVT();
const CallBase *CB = CLI.CB;
@@ -28408,10 +28407,11 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
ArgCCInfo.AnalyzeCallOperands(Outs, CC_RISCV);
// Check if it's really possible to do a tail call.
- if (IsTailCall)
- IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs);
+ if (CLI.getIsTailCall())
+ CLI.setIsTailCall(
+ isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs));
- if (IsTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
else if (CLI.CB && CLI.CB->isMustTailCall())
reportFatalInternalError("failed to perform tail call elimination on a "
@@ -28438,12 +28438,13 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment, Alignment,
/*IsVolatile=*/false,
- /*AlwaysInline=*/false, /*CI*/ nullptr, IsTailCall,
- MachinePointerInfo(), MachinePointerInfo());
+ /*AlwaysInline=*/false, /*CI*/ nullptr,
+ CLI.getIsTailCall(), MachinePointerInfo(),
+ MachinePointerInfo());
ByValArgs.push_back(FIPtr);
}
- if (!IsTailCall)
+ if (!CLI.getIsTailCall())
Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
// Copy argument values to their designated locations.
@@ -28537,7 +28538,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
// For musttail calls, reuse incoming indirect pointers instead of
// creating new stack temporaries. The incoming pointers point to the
// caller's caller's frame, which remains valid after a tail call.
- if (IsTailCall && CLI.CB && CLI.CB->isMustTailCall()) {
+ if (CLI.getIsTailCall() && CLI.CB && CLI.CB->isMustTailCall()) {
RISCVMachineFunctionInfo *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
unsigned CallArgIdx = Outs[OutIdx].OrigArgIndex;
@@ -28703,7 +28704,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);
} else {
assert(VA.isMemLoc() && "Argument not register or memory");
- assert((!IsTailCall || (CLI.CB && CLI.CB->isMustTailCall())) &&
+ assert((!CLI.getIsTailCall() || (CLI.CB && CLI.CB->isMustTailCall())) &&
"Tail call not allowed if stack is used for passing parameters");
// Work out the address of the stack slot.
@@ -28736,7 +28737,8 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
// reserved, if so report an error. Do the same for the return address if this
// is not a tailcall.
validateCCReservedRegs(RegsToPass, MF);
- if (!IsTailCall && MF.getSubtarget().isRegisterReservedByUser(RISCV::X1))
+ if (!CLI.getIsTailCall() &&
+ MF.getSubtarget().isRegisterReservedByUser(RISCV::X1))
MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
MF.getFunction(),
"Return address register required, but has been reserved."});
@@ -28805,14 +28807,14 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
CLI.CB && CLI.CB->hasFnAttr(Attribute::ReturnsTwice) &&
MF.getInfo<RISCVMachineFunctionInfo>()->hasCFProtectionBranch();
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
MF.getFrameInfo().setHasTailCall();
unsigned CallOpc =
NeedSWGuardedTail ? RISCVISD::SW_GUARDED_TAIL : RISCVISD::TAIL;
SDValue Ret = DAG.getNode(CallOpc, DL, NodeTys, Ops);
if (CLI.CFIType)
Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
- DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.getNoMerge());
DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
return Ret;
}
@@ -28832,7 +28834,7 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
if (CLI.CFIType)
Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.getNoMerge());
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
Glue = Chain.getValue(1);
@@ -28888,10 +28890,11 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
return Chain;
}
-bool RISCVTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool RISCVTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, RetCC_RISCV);
@@ -28900,7 +28903,7 @@ bool RISCVTargetLowering::CanLowerReturn(
SDValue
RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index af5ea77662d1e..ef3d6fdd61f40 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -302,16 +302,14 @@ class RISCVTargetLowering : public TargetLowering {
// Lower incoming arguments, copy physregs into vregs
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool IsVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp
index f96a8dce3d848..0939b09ebab3d 100644
--- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.cpp
@@ -31,7 +31,7 @@ RISCVMachineFunctionInfo::RISCVMachineFunctionInfo(const Function &F,
const RISCVSubtarget *STI) {
if (const auto *CFB = mdconst::extract_or_null<ConstantInt>(
F.getParent()->getModuleFlag("cf-protection-branch")))
- CFProtectionBranch = CFB->getZExtValue() != 0;
+ setCFProtectionBranch(CFB->getZExtValue() != 0);
// The default stack probe size is 4096 if the function has no
// stack-probe-size attribute. This is a safe default because it is the
diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
index 3aaf7466d7425..3022df243e0a3 100644
--- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
@@ -15,6 +15,7 @@
#include "RISCVSubtarget.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -75,7 +76,12 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo {
DenseMap<unsigned, Register> IncomingIndirectArgs;
/// Is there any vector argument or return?
- bool IsVectorCall = false;
+ bool getIsVectorCallFlag() const {
+ return InterruptCSRFrameIndexes.getFlag(0);
+ }
+ void setIsVectorCallFlag(bool Value) {
+ InterruptCSRFrameIndexes.setFlag(0, Value);
+ }
/// Registers that have been sign extended from i32.
SmallVector<Register, 8> SExt32Registers;
@@ -88,15 +94,26 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo {
unsigned QCIInterruptStackSize = 0;
/// Store Frame Indexes for Interrupt-Related CSR Spills.
- SmallVector<int, 2> InterruptCSRFrameIndexes;
+ llvm::SmallVectorWithFlags<int, 2, 3> InterruptCSRFrameIndexes;
int64_t StackProbeSize = 0;
/// Does it probe the stack for a dynamic allocation?
- bool HasDynamicAllocation = false;
+ bool getHasDynamicAllocation() const {
+ return InterruptCSRFrameIndexes.getFlag(1);
+ }
+ void setHasDynamicAllocation(bool Value) {
+ InterruptCSRFrameIndexes.setFlag(1, Value);
+ }
/// Whether the function has cf-protection-branch module flag set.
- bool CFProtectionBranch = false;
+ bool getCFProtectionBranch() const {
+ return InterruptCSRFrameIndexes.getFlag(2);
+ }
+ bool setCFProtectionBranch(bool Value) {
+ InterruptCSRFrameIndexes.setFlag(2, Value);
+ return Value;
+ }
public:
RISCVMachineFunctionInfo(const Function &F, const RISCVSubtarget *STI);
@@ -241,13 +258,13 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo {
void addSExt32Register(Register Reg);
bool isSExt32Register(Register Reg) const;
- bool isVectorCall() const { return IsVectorCall; }
- void setIsVectorCall() { IsVectorCall = true; }
+ bool isVectorCall() const { return getIsVectorCallFlag(); }
+ void setIsVectorCall() { setIsVectorCallFlag(true); }
- bool hasDynamicAllocation() const { return HasDynamicAllocation; }
- void setDynamicAllocation() { HasDynamicAllocation = true; }
+ bool hasDynamicAllocation() const { return getHasDynamicAllocation(); }
+ void setDynamicAllocation() { setHasDynamicAllocation(true); }
- bool hasCFProtectionBranch() const { return CFProtectionBranch; }
+ bool hasCFProtectionBranch() const { return getCFProtectionBranch(); }
};
} // end namespace llvm
diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index a2e9fb2e2cca1..a878f0b21cf7c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -680,7 +680,7 @@ bool SPIRVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
.addDef(ResVReg)
.addUse(GR->getSPIRVTypeID(RetType))
.add(Info.Callee);
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::MIFlag::NoMerge);
for (const auto &Arg : Info.OrigArgs) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizeZeroSizeArrays.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizeZeroSizeArrays.cpp
index abbdfdfecf6c4..3ae36c39ae808 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizeZeroSizeArrays.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizeZeroSizeArrays.cpp
@@ -16,6 +16,7 @@
#include "SPIRVUtils.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/InstVisitor.h"
@@ -78,8 +79,9 @@ class SPIRVLegalizeZeroSizeArraysImpl
const SPIRVTargetMachine &TM;
DenseMap<Type *, Type *> TypeMap;
DenseMap<GlobalVariable *, GlobalVariable *> GlobalMap;
- SmallVector<Instruction *, 16> ToErase;
- bool Modified = false;
+ llvm::SmallVectorWithFlags<Instruction *, 16> ToErase;
+ bool getModified() const { return ToErase.getFlag(0); }
+ void setModified(bool Value) { ToErase.setFlag(0, Value); }
};
class SPIRVLegalizeZeroSizeArraysLegacy : public ModulePass {
@@ -205,7 +207,7 @@ void SPIRVLegalizeZeroSizeArraysImpl::visitAllocaInst(AllocaInst &AI) {
NewAI->setDebugLoc(AI.getDebugLoc());
AI.replaceAllUsesWith(NewAI);
ToErase.push_back(&AI);
- Modified = true;
+ setModified(true);
}
void SPIRVLegalizeZeroSizeArraysImpl::visitLoadInst(LoadInst &LI) {
@@ -217,7 +219,7 @@ void SPIRVLegalizeZeroSizeArraysImpl::visitLoadInst(LoadInst &LI) {
if (shouldLegalizeInstType(ArrTy)) {
LI.replaceAllUsesWith(PoisonValue::get(LI.getType()));
ToErase.push_back(&LI);
- Modified = true;
+ setModified(true);
}
}
@@ -228,7 +230,7 @@ void SPIRVLegalizeZeroSizeArraysImpl::visitStoreInst(StoreInst &SI) {
ArrayType *ArrTy = dyn_cast<ArrayType>(StoreTy);
if (shouldLegalizeInstType(ArrTy)) {
ToErase.push_back(&SI);
- Modified = true;
+ setModified(true);
}
}
@@ -241,7 +243,7 @@ void SPIRVLegalizeZeroSizeArraysImpl::visitSelectInst(SelectInst &Sel) {
if (shouldLegalizeInstType(ArrTy)) {
Sel.replaceAllUsesWith(PoisonValue::get(Sel.getType()));
ToErase.push_back(&Sel);
- Modified = true;
+ setModified(true);
}
}
@@ -255,7 +257,7 @@ void SPIRVLegalizeZeroSizeArraysImpl::visitExtractValueInst(
if (shouldLegalizeInstType(ArrTy)) {
EVI.replaceAllUsesWith(PoisonValue::get(EVI.getType()));
ToErase.push_back(&EVI);
- Modified = true;
+ setModified(true);
}
}
@@ -270,7 +272,7 @@ void SPIRVLegalizeZeroSizeArraysImpl::visitInsertValueInst(
if (shouldLegalizeInstType(ArrTy)) {
IVI.replaceAllUsesWith(IVI.getAggregateOperand());
ToErase.push_back(&IVI);
- Modified = true;
+ setModified(true);
}
}
@@ -278,7 +280,7 @@ bool SPIRVLegalizeZeroSizeArraysImpl::runOnModule(Module &M) {
TypeMap.clear();
GlobalMap.clear();
ToErase.clear();
- Modified = false;
+ setModified(false);
// Runtime arrays are allowed for shaders, so we don't need to do anything.
if (TM.getSubtargetImpl()->isShader())
@@ -321,7 +323,7 @@ bool SPIRVLegalizeZeroSizeArraysImpl::runOnModule(Module &M) {
NewGV->setAlignment(GV.getAlign());
GlobalMap[&GV] = NewGV;
OldGlobals.push_back(&GV);
- Modified = true;
+ setModified(true);
}
// Second pass: replace uses, transfer names, and erase old globals.
@@ -339,7 +341,7 @@ bool SPIRVLegalizeZeroSizeArraysImpl::runOnModule(Module &M) {
for (Instruction *I : ToErase)
I->eraseFromParent();
- return Modified;
+ return getModified();
}
} // namespace
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
index 77d74f06ea5da..efdd0967f1688 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp
@@ -273,7 +273,7 @@ void SparcInstPrinter::printCTILabel(const MCInst *MI, uint64_t Address,
// we're running the disassembler), just print the immediate.
if (Op.isImm()) {
int64_t Offset = Op.getImm();
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address + Offset;
if (STI.getTargetTriple().isSPARC32())
Target &= 0xffffffff;
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index a61f919582070..b3239b603b714 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -237,10 +237,11 @@ static unsigned toCallerWindow(unsigned Reg) {
return Reg;
}
-bool SparcTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool SparcTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, Subtarget->is64Bit() ? RetCC_Sparc64
@@ -250,7 +251,7 @@ bool SparcTargetLowering::CanLowerReturn(
SDValue
SparcTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
if (Subtarget->is64Bit())
@@ -261,7 +262,7 @@ SparcTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
SDValue
SparcTargetLowering::LowerReturn_32(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
@@ -352,7 +353,7 @@ SparcTargetLowering::LowerReturn_32(SDValue Chain, CallingConv::ID CallConv,
SDValue
SparcTargetLowering::LowerReturn_64(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of the return value to locations.
@@ -428,8 +429,8 @@ SparcTargetLowering::LowerReturn_64(SDValue Chain, CallingConv::ID CallConv,
SDValue SparcTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
if (Subtarget->is64Bit())
return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins,
DL, DAG, InVals);
@@ -442,8 +443,8 @@ SDValue SparcTargetLowering::LowerFormalArguments(
/// pass FP values in FP registers for fastcc functions.
SDValue SparcTargetLowering::LowerFormalArguments_32(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
@@ -649,8 +650,8 @@ SDValue SparcTargetLowering::LowerFormalArguments_32(
// Lower formal arguments for the 64 bit ABI.
SDValue SparcTargetLowering::LowerFormalArguments_64(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
// Analyze arguments according to CC_Sparc64.
@@ -846,14 +847,13 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &dl = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
- SDValue Callee = CLI.Callee;
- bool &isTailCall = CLI.IsTailCall;
+ SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool isVarArg = CLI.IsVarArg;
+ bool isVarArg = CLI.getIsVarArg();
MachineFunction &MF = DAG.getMachineFunction();
LLVMContext &Ctx = *DAG.getContext();
EVT PtrVT = getPointerTy(MF.getDataLayout());
@@ -864,8 +864,9 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
*DAG.getContext());
CCInfo.AnalyzeCallOperands(Outs, CC_Sparc32);
- isTailCall = isTailCall && IsEligibleForTailCallOptimization(
- CCInfo, CLI, DAG.getMachineFunction());
+ CLI.setIsTailCall(
+ CLI.getIsTailCall() &&
+ IsEligibleForTailCallOptimization(CCInfo, CLI, DAG.getMachineFunction()));
// Get the size of the outgoing arguments stack space requirement.
unsigned ArgsSize = CCInfo.getStackSize();
@@ -905,9 +906,9 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
}
}
- assert(!isTailCall || ArgsSize == 0);
+ assert(!CLI.getIsTailCall() || ArgsSize == 0);
- if (!isTailCall)
+ if (!CLI.getIsTailCall())
Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, dl);
SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
@@ -956,7 +957,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
if (Flags.isSRet()) {
assert(VA.needsCustom());
- if (isTailCall)
+ if (CLI.getIsTailCall())
continue;
// store SRet argument in %sp+64
@@ -1114,7 +1115,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
// stuck together.
SDValue InGlue;
for (const auto &[OrigReg, N] : RegsToPass) {
- Register Reg = isTailCall ? OrigReg : toCallerWindow(OrigReg);
+ Register Reg = CLI.getIsTailCall() ? OrigReg : toCallerWindow(OrigReg);
Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
InGlue = Chain.getValue(1);
}
@@ -1137,7 +1138,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
if (hasStructRetAttr)
Ops.push_back(DAG.getTargetConstant(SRetArgSize, dl, MVT::i32));
for (const auto &[OrigReg, N] : RegsToPass) {
- Register Reg = isTailCall ? OrigReg : toCallerWindow(OrigReg);
+ Register Reg = CLI.getIsTailCall() ? OrigReg : toCallerWindow(OrigReg);
Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
}
@@ -1157,7 +1158,7 @@ SparcTargetLowering::LowerCall_32(TargetLowering::CallLoweringInfo &CLI,
if (InGlue.getNode())
Ops.push_back(InGlue);
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
DAG.getMachineFunction().getFrameInfo().setHasTailCall();
return DAG.getNode(SPISD::TAIL_CALL, dl, MVT::Other, Ops);
}
@@ -1292,12 +1293,13 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
- CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs,
- *DAG.getContext());
+ CCState CCInfo(CLI.CallConv, CLI.getIsVarArg(), DAG.getMachineFunction(),
+ ArgLocs, *DAG.getContext());
CCInfo.AnalyzeCallOperands(CLI.Outs, CC_Sparc64);
- CLI.IsTailCall = CLI.IsTailCall && IsEligibleForTailCallOptimization(
- CCInfo, CLI, DAG.getMachineFunction());
+ CLI.setIsTailCall(
+ CLI.getIsTailCall() &&
+ IsEligibleForTailCallOptimization(CCInfo, CLI, DAG.getMachineFunction()));
// Get the size of the outgoing arguments stack space requirement.
// The stack offset computed by CC_Sparc64 includes all arguments.
@@ -1310,15 +1312,15 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
ArgsSize = alignTo(ArgsSize, 16);
// Varargs calls require special treatment.
- if (CLI.IsVarArg)
+ if (CLI.getIsVarArg())
fixupVariableFloatArgs(ArgLocs, CLI.Outs);
- assert(!CLI.IsTailCall || ArgsSize == StackReserved);
+ assert(!CLI.getIsTailCall() || ArgsSize == StackReserved);
// Adjust the stack pointer to make room for the arguments.
// FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls
// with more than 6 arguments.
- if (!CLI.IsTailCall)
+ if (!CLI.getIsTailCall())
Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, DL);
// Collect the set of registers to pass to the function and their values.
@@ -1382,7 +1384,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
Register HiReg = VA.getLocReg();
Register LoReg = VA.getLocReg() + 1;
- if (!CLI.IsTailCall) {
+ if (!CLI.getIsTailCall()) {
HiReg = toCallerWindow(HiReg);
LoReg = toCallerWindow(LoReg);
}
@@ -1411,7 +1413,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
}
Register Reg = VA.getLocReg();
- if (!CLI.IsTailCall)
+ if (!CLI.getIsTailCall())
Reg = toCallerWindow(Reg);
RegsToPass.push_back(std::make_pair(Reg, Arg));
continue;
@@ -1481,7 +1483,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
Ops.push_back(InGlue);
// Now the call itself.
- if (CLI.IsTailCall) {
+ if (CLI.getIsTailCall()) {
DAG.getMachineFunction().getFrameInfo().setHasTailCall();
return DAG.getNode(SPISD::TAIL_CALL, DL, MVT::Other, Ops);
}
@@ -1498,8 +1500,8 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
- CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs,
- *DAG.getContext());
+ CCState RVInfo(CLI.CallConv, CLI.getIsVarArg(), DAG.getMachineFunction(),
+ RVLocs, *DAG.getContext());
// Set inreg flag manually for codegen generated library calls that
// return float.
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h
index b685b9ea9243e..3700738cd7643 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.h
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.h
@@ -86,17 +86,17 @@ namespace llvm {
SDValue
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerFormalArguments_32(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerFormalArguments_64(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
@@ -109,22 +109,19 @@ namespace llvm {
SmallVectorImpl<SDValue> &InVals) const;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const override;
SDValue LowerReturn_32(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const;
SDValue LowerReturn_64(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool IsVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp
index 1e9936194c94a..dd3cb7f473f1c 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp
@@ -184,7 +184,7 @@ void SystemZInstPrinterCommon::printPCRelOperand(const MCInst *MI,
// we're running the disassembler), just print the immediate.
if (MO.isImm()) {
int64_t Offset = MO.getImm();
- if (PrintBranchImmAsAddress)
+ if (getPrintBranchImmAsAddress())
markup(O, Markup::Target) << formatHex(Address + Offset);
else
markup(O, Markup::Immediate) << formatImm(Offset);
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 1813f9b97ceaa..72919764d33d4 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -933,7 +933,7 @@ bool SystemZVectorConstantInfo::isVectorConstantLegal(
const SystemZSubtarget &Subtarget) {
const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
if (!Subtarget.hasVector() ||
- (isFP128 && !Subtarget.hasVectorEnhancements1()))
+ (getIsFP128() && !Subtarget.hasVectorEnhancements1()))
return false;
// Try using VECTOR GENERATE BYTE MASK. This is the architecturally-
@@ -2037,8 +2037,8 @@ SDValue SystemZTargetLowering::joinRegisterPartsIntoValue(
// The first part of a split stack argument is at index I in Args (and
// ArgLocs). Return the type of a part and the number of them by reference.
-template <class ArgTy>
-static bool analyzeArgSplit(const SmallVectorImpl<ArgTy> &Args,
+template <class ArgRangeT>
+static bool analyzeArgSplit(const ArgRangeT &Args,
SmallVector<CCValAssign, 16> &ArgLocs, unsigned I,
MVT &PartVT, unsigned &NumParts) {
if (!Args[I].Flags.isSplit())
@@ -2059,8 +2059,8 @@ static bool analyzeArgSplit(const SmallVectorImpl<ArgTy> &Args,
SDValue SystemZTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
MachineRegisterInfo &MRI = MF.getRegInfo();
@@ -2261,7 +2261,7 @@ SDValue SystemZTargetLowering::LowerFormalArguments(
static bool canUseSiblingCall(const CCState &ArgCCInfo,
SmallVectorImpl<CCValAssign> &ArgLocs,
- SmallVectorImpl<ISD::OutputArg> &Outs) {
+ ArrayRef<ISD::OutputArg> Outs) {
// Punt if there are any indirect or stack arguments, or if the call
// needs the callee-saved argument register R6, or if the call uses
// the callee-saved register arguments SwiftSelf and SwiftError.
@@ -2373,14 +2373,13 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
- bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
MachineFunction &MF = DAG.getMachineFunction();
EVT PtrVT = getPointerTy(MF.getDataLayout());
LLVMContext &Ctx = *DAG.getContext();
@@ -2388,7 +2387,7 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
// FIXME: z/OS support to be added in later.
if (Subtarget.isTargetXPLINK64())
- IsTailCall = false;
+ CLI.setIsTailCall(false);
// Integer args <=32 bits should have an extension attribute.
verifyNarrowIntegerArgs_Call(Outs, &MF.getFunction(), Callee);
@@ -2400,14 +2399,14 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
// We don't support GuaranteedTailCallOpt, only automatically-detected
// sibling calls.
- if (IsTailCall && !canUseSiblingCall(ArgCCInfo, ArgLocs, Outs))
- IsTailCall = false;
+ if (CLI.getIsTailCall() && !canUseSiblingCall(ArgCCInfo, ArgLocs, Outs))
+ CLI.setIsTailCall(false);
// Get a count of how many bytes are to be pushed on the stack.
unsigned NumBytes = ArgCCInfo.getStackSize();
// Mark the start of the call.
- if (!IsTailCall)
+ if (!CLI.getIsTailCall())
Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);
// Copy argument values to their designated locations.
@@ -2524,7 +2523,7 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
} else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT);
Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee);
- } else if (IsTailCall) {
+ } else if (CLI.getIsTailCall()) {
Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R1D, Callee, Glue);
Glue = Chain.getValue(1);
Callee = DAG.getRegister(SystemZ::R1D, Callee.getValueType());
@@ -2559,13 +2558,13 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
// Emit the call.
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
- if (IsTailCall) {
+ if (CLI.getIsTailCall()) {
SDValue Ret = DAG.getNode(SystemZISD::SIBCALL, DL, NodeTys, Ops);
- DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.getNoMerge());
return Ret;
}
Chain = DAG.getNode(SystemZISD::CALL, DL, NodeTys, Ops);
- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.getNoMerge());
Glue = Chain.getValue(1);
// Mark the end of the call, which is glued to the call itself.
@@ -2626,10 +2625,11 @@ std::pair<SDValue, SDValue> SystemZTargetLowering::makeExternalCall(
return LowerCallTo(CLI);
}
-bool SystemZTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool SystemZTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
// Special case that we cannot easily detect in RetCC_SystemZ since
// i128 may not be a legal type.
for (auto &Out : Outs)
@@ -2644,7 +2644,7 @@ bool SystemZTargetLowering::CanLowerReturn(
SDValue
SystemZTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
@@ -11518,9 +11518,9 @@ bool SystemZTargetLowering::isInternal(const Function *Fn) const {
return Itr->second;
}
-void SystemZTargetLowering::
-verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
- const Function *F, SDValue Callee) const {
+void SystemZTargetLowering::verifyNarrowIntegerArgs_Call(
+ llvm::ArrayRef<ISD::OutputArg> Outs, const Function *F,
+ SDValue Callee) const {
// Temporarily only do the check when explicitly requested, until it can be
// enabled by default.
if (!EnableIntArgExtCheck)
@@ -11544,9 +11544,8 @@ verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
}
}
-void SystemZTargetLowering::
-verifyNarrowIntegerArgs_Ret(const SmallVectorImpl<ISD::OutputArg> &Outs,
- const Function *F) const {
+void SystemZTargetLowering::verifyNarrowIntegerArgs_Ret(
+ llvm::ArrayRef<ISD::OutputArg> Outs, const Function *F) const {
// Temporarily only do the check when explicitly requested, until it can be
// enabled by default.
if (!EnableIntArgExtCheck)
@@ -11563,7 +11562,7 @@ verifyNarrowIntegerArgs_Ret(const SmallVectorImpl<ISD::OutputArg> &Outs,
// Verify that narrow integer arguments are extended as required by the ABI.
// Return false if an error is found.
bool SystemZTargetLowering::verifyNarrowIntegerArgs(
- const SmallVectorImpl<ISD::OutputArg> &Outs) const {
+ llvm::ArrayRef<ISD::OutputArg> Outs) const {
if (!Subtarget.isTargetELF())
return true;
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
index 65463c48f3c4a..de04b23161940 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h
@@ -16,6 +16,7 @@
#include "SystemZ.h"
#include "SystemZInstrInfo.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/LibcallLoweringInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/SelectionDAG.h"
@@ -240,8 +241,7 @@ class SystemZTargetLowering : public TargetLowering {
unsigned NumParts, MVT PartVT, EVT ValueVT,
std::optional<CallingConv::ID> CC) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCall(CallLoweringInfo &CLI,
@@ -257,12 +257,10 @@ class SystemZTargetLowering : public TargetLowering {
SDLoc DL, SDValue Chain, bool IsStrict) const;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- LLVMContext &Context,
- const Type *RetTy) const override;
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
@@ -467,12 +465,11 @@ class SystemZTargetLowering : public TargetLowering {
private:
bool isInternal(const Function *Fn) const;
mutable std::map<const Function *, bool> IsInternalCache;
- void verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
+ void verifyNarrowIntegerArgs_Call(llvm::ArrayRef<ISD::OutputArg> Outs,
const Function *F, SDValue Callee) const;
- void verifyNarrowIntegerArgs_Ret(const SmallVectorImpl<ISD::OutputArg> &Outs,
+ void verifyNarrowIntegerArgs_Ret(llvm::ArrayRef<ISD::OutputArg> Outs,
const Function *F) const;
- bool
- verifyNarrowIntegerArgs(const SmallVectorImpl<ISD::OutputArg> &Outs) const;
+ bool verifyNarrowIntegerArgs(llvm::ArrayRef<ISD::OutputArg> Outs) const;
public:
};
@@ -483,15 +480,17 @@ struct SystemZVectorConstantInfo {
APInt SplatBits; // Smallest splat value.
APInt SplatUndef; // Bits correspoding to undef operands of the BVN.
unsigned SplatBitSize = 0;
- bool isFP128 = false;
+ bool getIsFP128() const { return OpVals.getFlag(0); }
+ void setIsFP128(bool Value) { OpVals.setFlag(0, Value); }
+
public:
unsigned Opcode = 0;
- SmallVector<unsigned, 2> OpVals;
+ llvm::SmallVectorWithFlags<unsigned, 2> OpVals;
MVT VecVT;
SystemZVectorConstantInfo(APInt IntImm);
SystemZVectorConstantInfo(APFloat FPImm)
: SystemZVectorConstantInfo(FPImm.bitcastToAPInt()) {
- isFP128 = (&FPImm.getSemantics() == &APFloat::IEEEquad());
+ setIsFP128((&FPImm.getSemantics() == &APFloat::IEEEquad()));
}
SystemZVectorConstantInfo(BuildVectorSDNode *BVN);
bool isVectorConstantLegal(const SystemZSubtarget &Subtarget);
diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp
index 6d9068ef579c6..5fa9025d0b8cd 100644
--- a/llvm/lib/Target/VE/VEISelLowering.cpp
+++ b/llvm/lib/Target/VE/VEISelLowering.cpp
@@ -65,10 +65,11 @@ CCAssignFn *getParamCC(CallingConv::ID CallConv, bool IsVarArg) {
}
}
-bool VETargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool VETargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
CCAssignFn *RetCC = getReturnCC(CallConv);
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
@@ -362,12 +363,12 @@ void VETargetLowering::initVPUActions() {
}
}
-SDValue
-VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &DL, SelectionDAG &DAG) const {
+SDValue VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL,
+ SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of the return value to locations.
SmallVector<CCValAssign, 16> RVLocs;
@@ -439,8 +440,8 @@ VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
SDValue VETargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
// Get the base offset of the incoming arguments stack space.
@@ -580,7 +581,7 @@ SDValue VETargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
auto PtrVT = getPointerTy(DAG.getDataLayout());
// VE target does not yet support tail call optimization.
- CLI.IsTailCall = false;
+ CLI.setIsTailCall(false);
// Get the base offset of the outgoing arguments stack space.
unsigned ArgsBaseOffset = Subtarget->getRsaSize();
@@ -589,8 +590,8 @@ SDValue VETargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
- CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs,
- *DAG.getContext());
+ CCState CCInfo(CLI.CallConv, CLI.getIsVarArg(), DAG.getMachineFunction(),
+ ArgLocs, *DAG.getContext());
// Allocate the preserved area first.
CCInfo.AllocateStack(ArgsPreserved, Align(8));
// We already allocated the preserved area, so the stack offset computed
@@ -599,11 +600,11 @@ SDValue VETargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// VE requires to use both register and stack for varargs or no-prototyped
// functions.
- bool UseBoth = CLI.IsVarArg;
+ bool UseBoth = CLI.getIsVarArg();
// Analyze operands again if it is required to store BOTH.
SmallVector<CCValAssign, 16> ArgLocs2;
- CCState CCInfo2(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(),
+ CCState CCInfo2(CLI.CallConv, CLI.getIsVarArg(), DAG.getMachineFunction(),
ArgLocs2, *DAG.getContext());
if (UseBoth)
CCInfo2.AnalyzeCallOperands(CLI.Outs, getParamCC(CLI.CallConv, true));
@@ -776,8 +777,8 @@ SDValue VETargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
- CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs,
- *DAG.getContext());
+ CCState RVInfo(CLI.CallConv, CLI.getIsVarArg(), DAG.getMachineFunction(),
+ RVLocs, *DAG.getContext());
// Set inreg flag manually for codegen generated library calls that
// return float.
diff --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h
index 487804194757e..9eb54e89ba4c9 100644
--- a/llvm/lib/Target/VE/VEISelLowering.h
+++ b/llvm/lib/Target/VE/VEISelLowering.h
@@ -134,8 +134,7 @@ class VETargetLowering : public TargetLowering {
EVT VT) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
@@ -143,12 +142,10 @@ class VETargetLowering : public TargetLowering {
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
- LLVMContext &Context,
- const Type *RetTy) const override;
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> ArgsFlags,
+ LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
index e5420fc1ef9d8..2dfcb74cd764a 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp
@@ -46,7 +46,8 @@ namespace llvm {
WebAssemblyAsmTypeCheck::WebAssemblyAsmTypeCheck(MCAsmParser &Parser,
const MCInstrInfo &MII,
bool Is64)
- : Parser(Parser), MII(MII), Is64(Is64) {}
+ : Parser(Parser), MII(MII),
+ LocalTypes(decltype(this->LocalTypes)::withFlags(unsigned(Is64))) {}
void WebAssemblyAsmTypeCheck::funcDecl(const wasm::WasmSignature &Sig) {
LocalTypes.assign(Sig.Params.begin(), Sig.Params.end());
@@ -265,7 +266,7 @@ bool WebAssemblyAsmTypeCheck::getGlobal(SMLoc ErrorLoc,
switch (SymRef->getSpecifier()) {
case WebAssembly::S_GOT:
case WebAssembly::S_GOT_TLS:
- Type = Is64 ? wasm::ValType::I64 : wasm::ValType::I32;
+ Type = getIs64() ? wasm::ValType::I64 : wasm::ValType::I32;
return false;
default:
break;
@@ -498,7 +499,7 @@ bool WebAssemblyAsmTypeCheck::typeCheck(SMLoc ErrorLoc, const MCInst &Inst,
}
if (Name == "memory.fill") {
- Type = Is64 ? wasm::ValType::I64 : wasm::ValType::I32;
+ Type = getIs64() ? wasm::ValType::I64 : wasm::ValType::I32;
bool Error = popType(ErrorLoc, Type);
Error |= popType(ErrorLoc, wasm::ValType::I32);
Error |= popType(ErrorLoc, Type);
@@ -506,7 +507,7 @@ bool WebAssemblyAsmTypeCheck::typeCheck(SMLoc ErrorLoc, const MCInst &Inst,
}
if (Name == "memory.copy") {
- Type = Is64 ? wasm::ValType::I64 : wasm::ValType::I32;
+ Type = getIs64() ? wasm::ValType::I64 : wasm::ValType::I32;
bool Error = popType(ErrorLoc, Type);
Error |= popType(ErrorLoc, Type);
Error |= popType(ErrorLoc, Type);
@@ -514,7 +515,7 @@ bool WebAssemblyAsmTypeCheck::typeCheck(SMLoc ErrorLoc, const MCInst &Inst,
}
if (Name == "memory.init") {
- Type = Is64 ? wasm::ValType::I64 : wasm::ValType::I32;
+ Type = getIs64() ? wasm::ValType::I64 : wasm::ValType::I32;
bool Error = popType(ErrorLoc, wasm::ValType::I32);
Error |= popType(ErrorLoc, wasm::ValType::I32);
Error |= popType(ErrorLoc, Type);
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.h b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.h
index e6fddf9806026..c2c04a222ab4b 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.h
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.h
@@ -16,6 +16,7 @@
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_ASMPARSER_TYPECHECK_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_ASMPARSER_TYPECHECK_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
@@ -40,9 +41,10 @@ class WebAssemblyAsmTypeCheck final {
bool IsLoop;
};
SmallVector<BlockInfo, 8> BlockInfoStack;
- SmallVector<wasm::ValType, 16> LocalTypes;
+ llvm::SmallVectorWithFlags<wasm::ValType, 16> LocalTypes;
wasm::WasmSignature LastSig;
- bool Is64;
+ bool getIs64() const { return LocalTypes.getFlag(0); }
+ void setIs64(bool Value) { LocalTypes.setFlag(0, Value); }
// checkTypes checks 'Types' against the value stack. popTypes checks 'Types'
// against the value stack and also pops them.
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp
index c8faeb7c7a40e..1e0cf2c05ceb0 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp
@@ -440,7 +440,7 @@ bool WebAssemblyCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
return false;
CallInst = MIRBuilder.buildInstrNoInsert(WebAssembly::CALL);
- if (Info.NoMerge)
+ if (Info.getNoMerge())
CallInst.setMIFlag(MachineInstr::MIFlag::NoMerge);
SmallVector<ArgInfo, 8> SplitArgs;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index b898dce8112b9..c6827113470d8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1304,21 +1304,21 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
fail(DL, DAG,
"WebAssembly doesn't support language-specific or target-specific "
"calling conventions yet");
- if (CLI.IsPatchPoint)
+ if (CLI.getIsPatchPointFlag())
fail(DL, DAG, "WebAssembly doesn't support patch point yet");
- if (CLI.IsTailCall) {
+ if (CLI.getIsTailCall()) {
auto NoTail = [&](const char *Msg) {
if (CLI.CB && CLI.CB->isMustTailCall())
fail(DL, DAG, Msg);
- CLI.IsTailCall = false;
+ CLI.setIsTailCall(false);
};
if (!Subtarget->hasTailCall())
NoTail("WebAssembly 'tail-call' feature not enabled");
// Varargs calls cannot be tail calls because the buffer is on the stack
- if (CLI.IsVarArg)
+ if (CLI.getIsVarArg())
NoTail("WebAssembly does not support varargs tail calls");
// Do not tail call unless caller and callee return types match
@@ -1365,8 +1365,8 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
NoTail("WebAssembly does not support tail calling with byval arguments");
}
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Ins = CLI.Ins;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
// The generic code may have added an sret argument. If we're lowering an
@@ -1416,7 +1416,7 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
NumFixedArgs += !Out.Flags.isVarArg();
}
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
auto PtrVT = getPointerTy(Layout);
// For swiftcc and swifttailcc, emit additional swiftself, swifterror, and
@@ -1571,7 +1571,7 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
Ops[0] = TableSet; // The new chain is the TableSet itself
}
- if (CLI.IsTailCall) {
+ if (CLI.getIsTailCall()) {
// ret_calls do not return values to the current frame
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
return DAG.getNode(WebAssemblyISD::RET_CALL, DL, NodeTys, Ops);
@@ -1590,7 +1590,7 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
bool WebAssemblyTargetLowering::CanLowerReturn(
CallingConv::ID /*CallConv*/, MachineFunction & /*MF*/, bool /*IsVarArg*/,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext & /*Context*/,
+ llvm::ArrayRef<ISD::OutputArg> Outs, LLVMContext & /*Context*/,
const Type *RetTy) const {
// WebAssembly can only handle returning tuples with multivalue enabled
return WebAssembly::canLowerReturn(Outs.size(), Subtarget);
@@ -1598,7 +1598,7 @@ bool WebAssemblyTargetLowering::CanLowerReturn(
SDValue WebAssemblyTargetLowering::LowerReturn(
SDValue Chain, CallingConv::ID CallConv, bool /*IsVarArg*/,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const {
assert(WebAssembly::canLowerReturn(Outs.size(), Subtarget) &&
@@ -1628,8 +1628,8 @@ SDValue WebAssemblyTargetLowering::LowerReturn(
SDValue WebAssemblyTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
if (!callingConvSupported(CallConv))
fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
index 04e6d6f2d9367..ed82444ee2a27 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -81,16 +81,14 @@ class WebAssemblyTargetLowering final : public TargetLowering {
SDValue LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
SelectionDAG &DAG) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool IsVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
diff --git a/llvm/lib/Target/X86/GISel/X86CallLowering.cpp b/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
index a2629c7281fc6..7ddbbe7724acd 100644
--- a/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
+++ b/llvm/lib/Target/X86/GISel/X86CallLowering.cpp
@@ -347,7 +347,7 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
auto MIB = MIRBuilder.buildInstrNoInsert(CallOpc)
.add(Info.Callee)
.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
- if (Info.NoMerge)
+ if (Info.getNoMerge())
MIB.setMIFlag(MachineInstr::MIFlag::NoMerge);
SmallVector<ArgInfo, 8> SplitArgs;
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
index 564636959f00f..cc6fd075150d5 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
@@ -439,7 +439,7 @@ 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) {
+ if (getSymbolizeOperands() && MIA) {
uint64_t Target;
if (MIA->evaluateBranch(*MI, 0, 0, Target))
return;
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp
index 5f6e007fe6a87..04b640e0352b0 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86InstPrinterCommon.cpp
@@ -356,12 +356,12 @@ void X86InstPrinterCommon::printRoundingControl(const MCInst *MI, unsigned Op,
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)
+ if (getSymbolizeOperands())
return;
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isImm()) {
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address + Op.getImm();
if (MAI.getCodePointerSize() == 4)
Target &= 0xffffffff;
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
index ff27005f52ea8..9df969b40cb31 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
@@ -381,7 +381,7 @@ 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) {
+ if (getSymbolizeOperands() && MIA) {
uint64_t Target;
if (MIA->evaluateBranch(*MI, 0, 0, Target))
return;
diff --git a/llvm/lib/Target/X86/X86CallFrameOptimization.cpp b/llvm/lib/Target/X86/X86CallFrameOptimization.cpp
index 3690a095987a8..4945dd3931d1e 100644
--- a/llvm/lib/Target/X86/X86CallFrameOptimization.cpp
+++ b/llvm/lib/Target/X86/X86CallFrameOptimization.cpp
@@ -25,6 +25,7 @@
#include "X86Subtarget.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -75,13 +76,15 @@ class X86CallFrameOptimizationImpl {
int64_t ExpectedDist = 0;
// The sequence of storing instructions used to pass the parameters
- SmallVector<MachineInstr *, 4> ArgStoreVector;
+ llvm::SmallVectorWithFlags<MachineInstr *, 4, 2> ArgStoreVector;
// True if this call site has no stack parameters
- bool NoStackParams = false;
+ bool getNoStackParams() const { return ArgStoreVector.getFlag(0); }
+ void setNoStackParams(bool Value) { ArgStoreVector.setFlag(0, Value); }
// True if this call site can use push instructions
- bool UsePush = false;
+ bool getUsePush() const { return ArgStoreVector.getFlag(1); }
+ void setUsePush(bool Value) { ArgStoreVector.setFlag(1, Value); }
};
typedef SmallVector<CallContext, 8> ContextVector;
@@ -212,10 +215,10 @@ bool X86CallFrameOptimizationImpl::isProfitable(MachineFunction &MF,
// Call sites where no parameters are passed on the stack
// do not affect the cost, since there needs to be no
// stack adjustment.
- if (CC.NoStackParams)
+ if (CC.getNoStackParams())
continue;
- if (!CC.UsePush) {
+ if (!CC.getUsePush()) {
// If we don't use pushes for a particular call site,
// we pay for not having a reserved call frame with an
// additional sub/add esp pair. The cost is ~3 bytes per instruction,
@@ -271,7 +274,7 @@ bool X86CallFrameOptimizationImpl::runOnMachineFunction(MachineFunction &MF) {
return false;
for (const auto &CC : CallSeqVector) {
- if (CC.UsePush) {
+ if (CC.getUsePush()) {
adjustCallSequence(MF, CC);
Changed = true;
}
@@ -373,7 +376,7 @@ void X86CallFrameOptimizationImpl::collectCallInfo(
// A zero adjustment means no stack parameters
if (!MaxAdjust) {
- Context.NoStackParams = true;
+ Context.setNoStackParams(true);
return;
}
@@ -490,7 +493,7 @@ void X86CallFrameOptimizationImpl::collectCallInfo(
if (*MMI != nullptr)
return;
- Context.UsePush = true;
+ Context.setUsePush(true);
}
void X86CallFrameOptimizationImpl::adjustCallSequence(
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index b972949b5727e..e4e458f566361 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -768,12 +768,11 @@ namespace llvm {
SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
- SmallVectorImpl<SDValue> &InVals,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
uint32_t *RegMask) const;
SDValue LowerMemArgument(SDValue Chain, CallingConv::ID CallConv,
- const SmallVectorImpl<ISD::InputArg> &ArgInfo,
+ llvm::ArrayRef<ISD::InputArg> ArgInfo,
const SDLoc &dl, SelectionDAG &DAG,
const CCValAssign &VA, MachineFrameInfo &MFI,
unsigned i) const;
@@ -866,14 +865,14 @@ namespace llvm {
SDValue
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const override;
@@ -894,10 +893,8 @@ namespace llvm {
ISD::NodeType ExtendKind) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- LLVMContext &Context,
- const Type *RetTy) const override;
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context, const Type *RetTy) const override;
const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
ArrayRef<MCPhysReg> getRoundingControlRegisters() const override;
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index af4ae285b8c70..7464a1df609d3 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -667,10 +667,11 @@ Value *X86TargetLowering::getSafeStackPointerLocation(
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
-bool X86TargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool X86TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
// Mingw64 GCC returns f128 via sret, and LLVM matches it for compatibility.
// This logic exists for libcalls, a frontend should explicitly use sret
// rather than rely on the sret demotion here.
@@ -778,12 +779,12 @@ static void Passv64i1ArgInRegs(
RegsToPass.push_back(std::make_pair(NextVA.getLocReg(), Hi));
}
-SDValue
-X86TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SDLoc &dl, SelectionDAG &DAG) const {
+SDValue X86TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &dl,
+ SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
@@ -1148,9 +1149,8 @@ static SDValue getPopFromX87Reg(SelectionDAG &DAG, SDValue Chain,
///
SDValue X86TargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
- uint32_t *RegMask) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals, uint32_t *RegMask) const {
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
// Assign locations to each value returned by this call.
@@ -1246,11 +1246,12 @@ SDValue X86TargetLowering::LowerCallResult(
/// set of incoming args of a call, contains an sret pointer that the callee
/// pops. This happens on most x86-32, System V platforms, unless register
/// parameters are in use (-mregparm=1+, regcallcc, etc).
-template <typename T>
-static bool hasCalleePopSRet(const SmallVectorImpl<T> &Args,
+template <typename ArgRangeT>
+static bool hasCalleePopSRet(const ArgRangeT &Args,
const SmallVectorImpl<CCValAssign> &ArgLocs,
const X86Subtarget &Subtarget) {
// Not C++20 (yet), so no concepts available.
+ using T = typename ArgRangeT::value_type;
static_assert(std::is_same_v<T, ISD::OutputArg> ||
std::is_same_v<T, ISD::InputArg>,
"requires ISD::OutputArg or ISD::InputArg");
@@ -1329,12 +1330,10 @@ bool X86TargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
return true;
}
-SDValue
-X86TargetLowering::LowerMemArgument(SDValue Chain, CallingConv::ID CallConv,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
- const CCValAssign &VA,
- MachineFrameInfo &MFI, unsigned i) const {
+SDValue X86TargetLowering::LowerMemArgument(
+ SDValue Chain, CallingConv::ID CallConv, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG, const CCValAssign &VA,
+ MachineFrameInfo &MFI, unsigned i) const {
// Create the nodes corresponding to a load from this parameter slot.
ISD::ArgFlagsTy Flags = Ins[i].Flags;
bool AlwaysUseMutable = shouldGuaranteeTCO(
@@ -1709,8 +1708,8 @@ void VarArgsLoweringHelper::lowerVarArgsParameters(SDValue &Chain,
SDValue X86TargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
@@ -2089,14 +2088,13 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &dl = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool &isTailCall = CLI.IsTailCall;
- bool isVarArg = CLI.IsVarArg;
+ bool isVarArg = CLI.getIsVarArg();
const auto *CB = CLI.CB;
MachineFunction &MF = DAG.getMachineFunction();
@@ -2118,7 +2116,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
bool IsNoTrackIndirectCall = IsIndirectCall && CB->doesNoCfCheck() &&
M->getModuleFlag("cf-protection-branch");
if (IsNoTrackIndirectCall)
- isTailCall = false;
+ CLI.setIsTailCall(false);
MachineFunction::CallSiteInfo CSInfo;
if (CallConv == CallingConv::X86_INTR)
@@ -2150,9 +2148,9 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
}
// We cannot guarantee TCO for mismatched calling conventions.
- if (isTailCall && ShouldGuaranteeTCO) {
+ if (CLI.getIsTailCall() && ShouldGuaranteeTCO) {
CallingConv::ID CallerCC = MF.getFunction().getCallingConv();
- isTailCall = (CallConv == CallerCC);
+ CLI.setIsTailCall((CallConv == CallerCC));
}
// Check if this tail call is a "sibling" call, which is loosely defined to
@@ -2161,15 +2159,15 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// sibling calls to avoid unnecessary argument copies.
bool IsMustTail = CLI.CB && CLI.CB->isMustTailCall();
bool IsSibcall = false;
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
IsSibcall = isEligibleForSiblingCallOpt(CLI, CCInfo, ArgLocs);
- isTailCall = IsSibcall || IsMustTail || ShouldGuaranteeTCO;
+ CLI.setIsTailCall(IsSibcall || IsMustTail || ShouldGuaranteeTCO);
}
- if (isTailCall)
+ if (CLI.getIsTailCall())
++NumTailCalls;
- if (IsMustTail && !isTailCall)
+ if (IsMustTail && !CLI.getIsTailCall())
report_fatal_error("failed to perform tail call elimination on a call "
"site marked musttail");
@@ -2187,7 +2185,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// A sibcall is ABI-compatible and does not need to adjust the stack pointer.
int FPDiff = 0;
- if (isTailCall && ShouldGuaranteeTCO && !IsSibcall) {
+ if (CLI.getIsTailCall() && ShouldGuaranteeTCO && !IsSibcall) {
// Lower arguments at fp - stackoffset + fpdiff.
unsigned NumBytesCallerPushed = X86Info->getBytesToPopOnReturn();
@@ -2215,7 +2213,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// temporary storage, and letting the register allocator spill if needed.
SmallVector<SDValue, 8> ByValTemporaries;
SDValue ByValTempChain;
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
// Use null SDValue to mean "no temporary recorded for this arg index".
ByValTemporaries.assign(OutVals.size(), SDValue());
@@ -2288,7 +2286,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (ArgLocs.back().getLocMemOffset() != 0)
report_fatal_error("any parameter with the inalloca attribute must be "
"the only memory argument");
- } else if (CLI.IsPreallocated) {
+ } else if (CLI.getIsPreallocatedFlag()) {
assert(ArgLocs.back().isMemLoc() &&
"cannot use preallocated attribute on a register "
"parameter");
@@ -2311,9 +2309,9 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SDValue RetAddrFrIdx;
// Load return address for tail calls.
- if (isTailCall && FPDiff)
- Chain = EmitTailCallLoadRetAddr(DAG, RetAddrFrIdx, Chain, isTailCall,
- Is64Bit, FPDiff, dl);
+ if (CLI.getIsTailCall() && FPDiff)
+ Chain = EmitTailCallLoadRetAddr(DAG, RetAddrFrIdx, Chain,
+ CLI.getIsTailCall(), Is64Bit, FPDiff, dl);
SmallVector<std::pair<Register, SDValue>, 8> RegsToPass;
SmallVector<SDValue, 8> MemOpChains;
@@ -2414,7 +2412,8 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (ShadowReg)
RegsToPass.push_back(std::make_pair(ShadowReg, Arg));
}
- } else if (!IsSibcall && (!isTailCall || (isByVal && !IsMustTail))) {
+ } else if (!IsSibcall &&
+ (!CLI.getIsTailCall() || (isByVal && !IsMustTail))) {
assert(VA.isMemLoc());
if (!StackPtr.getNode())
StackPtr = DAG.getCopyFromReg(Chain, dl, RegInfo->getStackRegister(),
@@ -2430,7 +2429,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (Subtarget.isPICStyleGOT()) {
// ELF / PIC requires GOT in the EBX register before function calls via PLT
// GOT pointer.
- if (!isTailCall) {
+ if (!CLI.getIsTailCall()) {
// Only PLT calls (GlobalAddress or ExternalSymbol) require the GOT in
// EBX. Indirect calls through a register or an absolute address do not
// go through the PLT and do not need EBX to hold the GOT base.
@@ -2492,7 +2491,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// For tail calls lower the arguments to the 'real' stack slots. Sibcalls
// don't need this because the eligibility check rejects calls that require
// shuffling arguments passed in memory.
- if (isTailCall && !IsSibcall) {
+ if (CLI.getIsTailCall() && !IsSibcall) {
// Force all the incoming stack arguments to be loaded from the stack
// before any new outgoing arguments or the return address are stored to the
// stack, because the outgoing stack slots may alias the incoming argument
@@ -2608,7 +2607,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVector<SDValue, 8> Ops;
- if (!IsSibcall && isTailCall && !IsMustTail) {
+ if (!IsSibcall && CLI.getIsTailCall() && !IsMustTail) {
Chain = DAG.getCALLSEQ_END(Chain, NumBytesToPop, 0, InGlue, dl);
InGlue = Chain.getValue(1);
}
@@ -2616,7 +2615,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Ops.push_back(Chain);
Ops.push_back(Callee);
- if (isTailCall)
+ if (CLI.getIsTailCall())
Ops.push_back(DAG.getSignedTargetConstant(FPDiff, dl, MVT::i32));
// Add argument registers to the end of the list so that they are known live
@@ -2700,7 +2699,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (InGlue.getNode())
Ops.push_back(InGlue);
- if (isTailCall) {
+ if (CLI.getIsTailCall()) {
// We used to do:
//// If this is the first return lowered for this function, add the regs
//// to the liveout set for the function.
@@ -2715,7 +2714,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (IsCFICall)
Ret.getNode()->setCFIType(CLI.CFIType->getZExtValue());
- DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Ret.getNode(), CLI.getNoMerge());
DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));
return Ret;
}
@@ -2732,7 +2731,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Calls with a "clang.arc.attachedcall" bundle are special. They should be
// expanded to the call, directly followed by a special marker sequence and
// a call to a ObjC library function. Use the CALL_RVMARKER to do that.
- assert(!isTailCall &&
+ assert(!CLI.getIsTailCall() &&
"tail calls cannot be marked with clang.arc.attachedcall");
assert(Is64Bit && "clang.arc.attachedcall is only supported in 64bit mode");
@@ -2751,7 +2750,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
Chain.getNode()->setCFIType(CLI.CFIType->getZExtValue());
InGlue = Chain.getValue(1);
- DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
+ DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.getNoMerge());
DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
// Save heapallocsite metadata.
@@ -2977,12 +2976,12 @@ bool X86TargetLowering::isEligibleForSiblingCallOpt(
TargetLowering::CallLoweringInfo &CLI, CCState &CCInfo,
SmallVectorImpl<CCValAssign> &ArgLocs) const {
SelectionDAG &DAG = CLI.DAG;
- const SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ const auto &Outs = CLI.Outs;
const SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- const SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ const auto &Ins = CLI.Ins;
SDValue Callee = CLI.Callee;
CallingConv::ID CalleeCC = CLI.CallConv;
- bool isVarArg = CLI.IsVarArg;
+ bool isVarArg = CLI.getIsVarArg();
if (!mayTailCallThisCC(CalleeCC))
return false;
diff --git a/llvm/lib/Target/X86/X86MachineFunctionInfo.h b/llvm/lib/Target/X86/X86MachineFunctionInfo.h
index 1cfe86d57071f..87c4da1a67737 100644
--- a/llvm/lib/Target/X86/X86MachineFunctionInfo.h
+++ b/llvm/lib/Target/X86/X86MachineFunctionInfo.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -118,11 +119,9 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
unsigned NumLocalDynamics = 0;
/// HasPushSequences - Keeps track of whether this function uses sequences
/// of pushes to pass function parameters.
- bool HasPushSequences = false;
/// True if the function recovers from an SEH exception, and therefore needs
/// to spill and restore the frame pointer.
- bool HasSEHFramePtrSave = false;
/// The frame index of a stack object containing the original frame pointer
/// used to address arguments in a function using a base pointer.
@@ -147,7 +146,6 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
/// Whether this function has an extended frame record [Ctx, RBP, Return
/// addr]. If so, bit 60 of the in-memory frame pointer will be 1 to enable
/// other tools to detect the extended record.
- bool HasSwiftAsyncContext = false;
/// Candidate registers for push2/pop2
std::set<Register> CandidatesForPush2Pop2;
@@ -155,7 +153,6 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
/// True if this function has CFI directives that adjust the CFA.
/// This is used to determine if we should direct the debugger to use
/// the CFA instead of the stack pointer.
- bool HasCFIAdjustCfa = false;
MachineInstr *StackPtrSaveMI = nullptr;
@@ -164,14 +161,11 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
// Preallocated fields are only used during isel.
// FIXME: Can we find somewhere else to store these?
DenseMap<const Value *, size_t> PreallocatedIds;
- SmallVector<size_t, 0> PreallocatedStackSizes;
- SmallVector<SmallVector<size_t, 4>, 0> PreallocatedArgOffsets;
+ llvm::SmallVectorWithFlags<size_t, 0, 4> PreallocatedStackSizes;
+ llvm::SmallVectorWithFlags<SmallVector<size_t, 4>, 0, 4>
+ PreallocatedArgOffsets;
// True if a function clobbers FP/BP according to its calling convention.
- bool FPClobberedByCall = false;
- bool BPClobberedByCall = false;
- bool FPClobberedByInvoke = false;
- bool BPClobberedByInvoke = false;
private:
/// ForwardedMustTailRegParms - A list of virtual and physical registers
@@ -194,8 +188,10 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
bool getForceFramePointer() const { return ForceFramePointer;}
void setForceFramePointer(bool forceFP) { ForceFramePointer = forceFP; }
- bool getHasPushSequences() const { return HasPushSequences; }
- void setHasPushSequences(bool HasPush) { HasPushSequences = HasPush; }
+ bool getHasPushSequences() const { return PreallocatedArgOffsets.getFlag(0); }
+ void setHasPushSequences(bool HasPush) {
+ PreallocatedArgOffsets.setFlag(0, HasPush);
+ }
bool getRestoreBasePointer() const { return RestoreBasePointerOffset!=0; }
void setRestoreBasePointer(const MachineFunction *MF);
@@ -247,8 +243,10 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
unsigned getNumLocalDynamicTLSAccesses() const { return NumLocalDynamics; }
void incNumLocalDynamicTLSAccesses() { ++NumLocalDynamics; }
- bool getHasSEHFramePtrSave() const { return HasSEHFramePtrSave; }
- void setHasSEHFramePtrSave(bool V) { HasSEHFramePtrSave = V; }
+ bool getHasSEHFramePtrSave() const {
+ return PreallocatedArgOffsets.getFlag(1);
+ }
+ void setHasSEHFramePtrSave(bool V) { PreallocatedArgOffsets.setFlag(1, V); }
int getSEHFramePtrSaveIndex() const { return SEHFramePtrSaveIndex; }
void setSEHFramePtrSaveIndex(int Index) { SEHFramePtrSaveIndex = Index; }
@@ -276,8 +274,10 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
bool hasPreallocatedCall() const { return HasPreallocatedCall; }
void setHasPreallocatedCall(bool v) { HasPreallocatedCall = v; }
- bool hasSwiftAsyncContext() const { return HasSwiftAsyncContext; }
- void setHasSwiftAsyncContext(bool v) { HasSwiftAsyncContext = v; }
+ bool hasSwiftAsyncContext() const {
+ return PreallocatedArgOffsets.getFlag(2);
+ }
+ void setHasSwiftAsyncContext(bool v) { PreallocatedArgOffsets.setFlag(2, v); }
bool isCandidateForPush2Pop2(Register Reg) const {
return CandidatesForPush2Pop2.find(Reg) != CandidatesForPush2Pop2.end();
@@ -289,8 +289,8 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
return CandidatesForPush2Pop2.size();
}
- bool hasCFIAdjustCfa() const { return HasCFIAdjustCfa; }
- void setHasCFIAdjustCfa(bool v) { HasCFIAdjustCfa = v; }
+ bool hasCFIAdjustCfa() const { return PreallocatedArgOffsets.getFlag(3); }
+ void setHasCFIAdjustCfa(bool v) { PreallocatedArgOffsets.setFlag(3, v); }
void setStackPtrSaveMI(MachineInstr *MI) { StackPtrSaveMI = MI; }
MachineInstr *getStackPtrSaveMI() const { return StackPtrSaveMI; }
@@ -327,17 +327,25 @@ class X86MachineFunctionInfo : public MachineFunctionInfo {
return PreallocatedArgOffsets[Id];
}
- bool getFPClobberedByCall() const { return FPClobberedByCall; }
- void setFPClobberedByCall(bool C) { FPClobberedByCall = C; }
+ bool getFPClobberedByCall() const {
+ return PreallocatedStackSizes.getFlag(0);
+ }
+ void setFPClobberedByCall(bool C) { PreallocatedStackSizes.setFlag(0, C); }
- bool getBPClobberedByCall() const { return BPClobberedByCall; }
- void setBPClobberedByCall(bool C) { BPClobberedByCall = C; }
+ bool getBPClobberedByCall() const {
+ return PreallocatedStackSizes.getFlag(1);
+ }
+ void setBPClobberedByCall(bool C) { PreallocatedStackSizes.setFlag(1, C); }
- bool getFPClobberedByInvoke() const { return FPClobberedByInvoke; }
- void setFPClobberedByInvoke(bool C) { FPClobberedByInvoke = C; }
+ bool getFPClobberedByInvoke() const {
+ return PreallocatedStackSizes.getFlag(2);
+ }
+ void setFPClobberedByInvoke(bool C) { PreallocatedStackSizes.setFlag(2, C); }
- bool getBPClobberedByInvoke() const { return BPClobberedByInvoke; }
- void setBPClobberedByInvoke(bool C) { BPClobberedByInvoke = C; }
+ bool getBPClobberedByInvoke() const {
+ return PreallocatedStackSizes.getFlag(3);
+ }
+ void setBPClobberedByInvoke(bool C) { PreallocatedStackSizes.setFlag(3, C); }
};
} // End llvm namespace
diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp
index 8b193cfab7a74..8be8406eee3d2 100644
--- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp
@@ -904,17 +904,16 @@ XCoreTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &dl = CLI.DL;
- SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
- SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
- SDValue Callee = CLI.Callee;
- bool &isTailCall = CLI.IsTailCall;
+ SDValue Callee = CLI.Callee;
CallingConv::ID CallConv = CLI.CallConv;
- bool isVarArg = CLI.IsVarArg;
+ bool isVarArg = CLI.getIsVarArg();
// XCore target does not yet support tail call optimization.
- isTailCall = false;
+ CLI.setIsTailCall(false);
// For now, only CallingConv::C implemented
switch (CallConv)
@@ -923,8 +922,9 @@ XCoreTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
report_fatal_error("Unsupported calling convention");
case CallingConv::Fast:
case CallingConv::C:
- return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
- Outs, OutVals, Ins, dl, DAG, InVals);
+ return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg,
+ CLI.getIsTailCall(), Outs, OutVals, Ins, dl, DAG,
+ InVals);
}
}
@@ -977,10 +977,10 @@ static SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
/// TODO: isTailCall, sret.
SDValue XCoreTargetLowering::LowerCCCCallTo(
SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ bool isTailCall, llvm::ArrayRef<ISD::OutputArg> Outs,
+ const SmallVectorImpl<SDValue> &OutVals, llvm::ArrayRef<ISD::InputArg> Ins,
+ const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -1107,8 +1107,8 @@ namespace {
/// XCore formal arguments implementation
SDValue XCoreTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
switch (CallConv)
{
default:
@@ -1126,8 +1126,8 @@ SDValue XCoreTargetLowering::LowerFormalArguments(
/// TODO: sret
SDValue XCoreTargetLowering::LowerCCCArguments(
SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
@@ -1282,11 +1282,11 @@ SDValue XCoreTargetLowering::LowerCCCArguments(
// Return Value Calling Convention Implementation
//===----------------------------------------------------------------------===//
-bool XCoreTargetLowering::
-CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- LLVMContext &Context, const Type *RetTy) const {
+bool XCoreTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool isVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
if (!CCInfo.CheckReturn(Outs, RetCC_XCore))
@@ -1299,7 +1299,7 @@ CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
SDValue
XCoreTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const {
diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.h b/llvm/lib/Target/XCore/XCoreISelLowering.h
index a965fe93f093b..eeeb4e24ec821 100644
--- a/llvm/lib/Target/XCore/XCoreISelLowering.h
+++ b/llvm/lib/Target/XCore/XCoreISelLowering.h
@@ -80,17 +80,15 @@ namespace llvm {
// Lower Operand helpers
SDValue LowerCCCArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee,
CallingConv::ID CallConv, bool isVarArg,
- bool isTailCall,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isTailCall, llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
SDValue getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV,
SelectionDAG &DAG) const;
@@ -139,8 +137,8 @@ namespace llvm {
SDValue
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- const SDLoc &dl, SelectionDAG &DAG,
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &dl,
+ SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue
@@ -148,13 +146,12 @@ namespace llvm {
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> ArgsFlags,
LLVMContext &Context, const Type *RetTy) const override;
};
}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
index 083e4ecaf93a5..615c85de4767b 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -123,7 +123,7 @@ void XtensaInstPrinter::printCallOperand(const MCInst *MI, uint64_t Address,
const MCOperand &MC = MI->getOperand(OpNum);
if (MC.isImm()) {
int64_t Val = MC.getImm() + 4;
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address;
Target &= ~0x3;
Target += Val & (~0x3);
@@ -145,7 +145,7 @@ void XtensaInstPrinter::printL32RTarget(const MCInst *MI, uint64_t Address,
const MCOperand &MC = MI->getOperand(OpNum);
if (MC.isImm()) {
int64_t Value = MI->getOperand(OpNum).getImm();
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = (Address + 0x3) & (~0x3);
Value &= ~0x3;
Target += Value;
@@ -166,7 +166,7 @@ void XtensaInstPrinter::printL32RTarget(const MCInst *MI, uint64_t Address,
void XtensaInstPrinter::printPCRelImm(uint64_t Address, int64_t Offset,
raw_ostream &O) {
- if (PrintBranchImmAsAddress) {
+ if (getPrintBranchImmAsAddress()) {
uint64_t Target = Address + Offset;
Target &= 0xffffffff;
O << formatHex(Target);
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index 59e356da1fdc8..ece27651ee215 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -469,8 +469,8 @@ CCAssignFn *XtensaTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
SDValue XtensaTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
- SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ llvm::ArrayRef<ISD::InputArg> Ins, const SDLoc &DL, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();
@@ -618,21 +618,20 @@ XtensaTargetLowering::LowerCall(CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
SelectionDAG &DAG = CLI.DAG;
SDLoc &DL = CLI.DL;
- SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
+ auto &Outs = CLI.Outs;
SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
- SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins;
+ auto &Ins = CLI.Ins;
SDValue Chain = CLI.Chain;
SDValue Callee = CLI.Callee;
- bool &IsTailCall = CLI.IsTailCall;
CallingConv::ID CallConv = CLI.CallConv;
- bool IsVarArg = CLI.IsVarArg;
+ bool IsVarArg = CLI.getIsVarArg();
MachineFunction &MF = DAG.getMachineFunction();
EVT PtrVT = getPointerTy(DAG.getDataLayout());
const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
// TODO: Support tail call optimization.
- IsTailCall = false;
+ CLI.setIsTailCall(false);
// Analyze the operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -666,7 +665,7 @@ XtensaTargetLowering::LowerCall(CallLoweringInfo &CLI,
assert(VA.isMemLoc());
assert(Flags.getByValSize() &&
"ByVal args of size 0 should have been ignored by front-end.");
- assert(!IsTailCall &&
+ assert(!CLI.getIsTailCall() &&
"Do not tail-call optimize if there is a byval argument.");
if (!StackPtr.getNode())
@@ -803,10 +802,11 @@ XtensaTargetLowering::LowerCall(CallLoweringInfo &CLI,
return Chain;
}
-bool XtensaTargetLowering::CanLowerReturn(
- CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
- const Type *RetTy) const {
+bool XtensaTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+ MachineFunction &MF, bool IsVarArg,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
+ LLVMContext &Context,
+ const Type *RetTy) const {
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
return CCInfo.CheckReturn(Outs, RetCC_Xtensa);
@@ -815,7 +815,7 @@ bool XtensaTargetLowering::CanLowerReturn(
SDValue
XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &DL, SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
index f62cf70a6fbb1..03d8c0885236a 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
@@ -72,8 +72,7 @@ class XtensaTargetLowering : public TargetLowering {
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
- bool isVarArg,
- const SmallVectorImpl<ISD::InputArg> &Ins,
+ bool isVarArg, llvm::ArrayRef<ISD::InputArg> Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
@@ -81,12 +80,11 @@ class XtensaTargetLowering : public TargetLowering {
SmallVectorImpl<SDValue> &InVals) const override;
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
- bool isVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ bool isVarArg, llvm::ArrayRef<ISD::OutputArg> Outs,
LLVMContext &Context, const Type *RetTy) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
+ llvm::ArrayRef<ISD::OutputArg> Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
SelectionDAG &DAG) const override;
diff --git a/llvm/lib/Transforms/Coroutines/SpillUtils.cpp b/llvm/lib/Transforms/Coroutines/SpillUtils.cpp
index 5078b3a026ae1..67d5a1bba006a 100644
--- a/llvm/lib/Transforms/Coroutines/SpillUtils.cpp
+++ b/llvm/lib/Transforms/Coroutines/SpillUtils.cpp
@@ -409,7 +409,7 @@ struct AllocaUseVisitor : PtrUseVisitor<AllocaUseVisitor> {
if (DT.dominates(CoroShape.CoroBegin, &I) || !usedAfterCoroBegin(I))
return;
- if (!IsOffsetKnown) {
+ if (!isOffsetKnown()) {
AliasOffetMap[&I].reset();
} else {
auto [Itr, Inserted] = AliasOffetMap.try_emplace(&I, Offset);
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 9e44f0d657794..36502ec642ddb 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -3236,7 +3236,7 @@ void InformationCache::initializeInformationCache(const Function &CF,
// initialize the cache eagerly which would look the same to the users.
Function &F = const_cast<Function &>(CF);
- FI.IsKernel = F.hasFnAttribute("kernel");
+ FI.setIsKernel(F.hasFnAttribute("kernel"));
// Walk all instructions to find interesting instructions that might be
// queried by abstract attributes during their initialization or update.
@@ -3289,10 +3289,10 @@ void InformationCache::initializeInformationCache(const Function &CF,
fillMapFromAssume(*Assume, KnowledgeMap);
AddToAssumeUsesMap(*Assume->getArgOperand(0));
} else if (cast<CallInst>(I).isMustTailCall()) {
- FI.ContainsMustTailCall = true;
+ FI.setContainsMustTailCall(true);
if (auto *Callee = dyn_cast_if_present<Function>(
cast<CallInst>(I).getCalledOperand()))
- getFunctionInfo(*Callee).CalledViaMustTail = true;
+ getFunctionInfo(*Callee).setCalledViaMustTail(true);
}
[[fallthrough]];
case Instruction::CallBr:
@@ -3396,11 +3396,11 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
// determine if it is part of a must-tail call edge. This will influence what
// attributes we can derive.
InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(F);
- if (!isModulePass() && !FI.CalledViaMustTail) {
+ if (!isModulePass() && !FI.getCalledViaMustTail()) {
for (const Use &U : F.uses())
if (const auto *CB = dyn_cast<CallBase>(U.getUser()))
if (CB->isCallee(&U) && CB->isMustTailCall())
- FI.CalledViaMustTail = true;
+ FI.setCalledViaMustTail(true);
}
IRPosition FPos = IRPosition::function(F);
diff --git a/llvm/lib/Transforms/IPO/BlockExtractor.cpp b/llvm/lib/Transforms/IPO/BlockExtractor.cpp
index 9bede77c8ac89..4d5377a029393 100644
--- a/llvm/lib/Transforms/IPO/BlockExtractor.cpp
+++ b/llvm/lib/Transforms/IPO/BlockExtractor.cpp
@@ -13,6 +13,7 @@
#include "llvm/Transforms/IPO/BlockExtractor.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
@@ -41,7 +42,9 @@ static cl::opt<bool>
namespace {
class BlockExtractor {
public:
- BlockExtractor(bool EraseFunctions) : EraseFunctions(EraseFunctions) {}
+ BlockExtractor(bool EraseFunctions)
+ : BlocksByName(
+ decltype(BlocksByName)::withFlags(unsigned(EraseFunctions))) {}
bool runOnModule(Module &M);
void
init(const std::vector<std::vector<BasicBlock *>> &GroupsOfBlocksToExtract) {
@@ -52,9 +55,11 @@ class BlockExtractor {
private:
std::vector<std::vector<BasicBlock *>> GroupsOfBlocks;
- bool EraseFunctions;
+ bool getEraseFunctions() const { return BlocksByName.getFlag(0); }
+ void setEraseFunctions(bool Value) { BlocksByName.setFlag(0, Value); }
/// Map a function name to groups of blocks.
- SmallVector<std::pair<std::string, SmallVector<std::string, 4>>, 4>
+ llvm::SmallVectorWithFlags<
+ std::pair<std::string, SmallVector<std::string, 4>>, 4>
BlocksByName;
void loadFile();
@@ -181,7 +186,7 @@ bool BlockExtractor::runOnModule(Module &M) {
}
// Erase the functions.
- if (EraseFunctions || BlockExtractorEraseFuncs) {
+ if (getEraseFunctions() || BlockExtractorEraseFuncs) {
for (Function *F : Functions) {
LLVM_DEBUG(dbgs() << "BlockExtractor: Trying to delete " << F->getName()
<< "\n");
diff --git a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
index 97183c76a079b..36f5a7cd519c6 100644
--- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
+++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp
@@ -28,6 +28,7 @@
#include "llvm/Transforms/IPO/HotColdSplitting.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
@@ -464,7 +465,7 @@ class OutliningRegion {
/// A list of (block, score) pairs. A block's score is non-zero iff it's a
/// viable sub-region entry point. Blocks with higher scores are better entry
/// points (i.e. they are more distant ancestors of the sink block).
- SmallVector<BlockTy, 0> Blocks = {};
+ llvm::SmallVectorWithFlags<BlockTy, 0> Blocks = {};
/// The suggested entry point into the region. If the region has multiple
/// entry points, all blocks within the region may not be reachable from this
@@ -472,7 +473,8 @@ class OutliningRegion {
BasicBlock *SuggestedEntryPoint = nullptr;
/// Whether the entire function is cold.
- bool EntireFunctionCold = false;
+ bool getEntireFunctionCold() const { return Blocks.getFlag(0); }
+ void setEntireFunctionCold(bool Value) { Blocks.setFlag(0, Value); }
/// If \p BB is a viable entry point, return \p Score. Return 0 otherwise.
static unsigned getEntryPointScore(BasicBlock &BB, unsigned Score) {
@@ -521,7 +523,7 @@ class OutliningRegion {
// If the predecessor is cold and has no predecessors, the entire
// function must be cold.
if (SinkPostDom && pred_empty(&PredBB)) {
- ColdRegion->EntireFunctionCold = true;
+ ColdRegion->setEntireFunctionCold(true);
return Regions;
}
@@ -554,7 +556,7 @@ class OutliningRegion {
if (mayExtractBlock(SinkBB)) {
addBlockToRegion(&SinkBB, SinkScore);
if (pred_empty(&SinkBB)) {
- ColdRegion->EntireFunctionCold = true;
+ ColdRegion->setEntireFunctionCold(true);
return Regions;
}
} else {
@@ -600,7 +602,7 @@ class OutliningRegion {
ArrayRef<std::pair<BasicBlock *, unsigned>> blocks() const { return Blocks; }
/// Whether the entire function containing this region is cold.
- bool isEntireFunctionCold() const { return EntireFunctionCold; }
+ bool isEntireFunctionCold() const { return getEntireFunctionCold(); }
/// Remove a sub-region from this region and return it as a block sequence.
BlockSequence takeSingleEntrySubRegion(DominatorTree &DT) {
diff --git a/llvm/lib/Transforms/IPO/Instrumentor.cpp b/llvm/lib/Transforms/IPO/Instrumentor.cpp
index 18a3c86dcfe71..25b938e0f3382 100644
--- a/llvm/lib/Transforms/IPO/Instrumentor.cpp
+++ b/llvm/lib/Transforms/IPO/Instrumentor.cpp
@@ -391,7 +391,7 @@ bool InstrumentorImpl::instrumentFunction(Function &Fn) {
Value *FPtr = &Fn;
for (auto &[Name, IO] :
IConf.IChoices[InstrumentationLocation::FUNCTION_PRE]) {
- if (!IO->Enabled)
+ if (!IO->getEnabled())
continue;
// Count epochs eagerly.
++IIRB.Epoch;
@@ -405,7 +405,7 @@ bool InstrumentorImpl::instrumentFunction(Function &Fn) {
for (auto &[Name, IO] :
IConf.IChoices[InstrumentationLocation::FUNCTION_POST]) {
- if (!IO->Enabled)
+ if (!IO->getEnabled())
continue;
// Count epochs eagerly.
++IIRB.Epoch;
@@ -459,7 +459,7 @@ bool InstrumentorImpl::instrumentModule() {
Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
for (auto &ChoiceIt : IConf.IChoices[Loc]) {
auto *IO = ChoiceIt.second;
- if (!IO->Enabled)
+ if (!IO->getEnabled())
continue;
if (!YtorFn) {
YtorFn = CreateYtor(IsPRE);
@@ -483,7 +483,7 @@ bool InstrumentorImpl::instrumentModule() {
Function *&YtorFn = IsPRE ? CtorFn : DtorFn;
for (auto &ChoiceIt : IConf.IChoices[Loc]) {
auto *IO = ChoiceIt.second;
- if (!IO->Enabled)
+ if (!IO->getEnabled())
continue;
if (!YtorFn) {
YtorFn = CreateYtor(IsPRE);
@@ -530,11 +530,11 @@ bool InstrumentorImpl::instrument() {
for (auto &[Name, IO] :
IConf.IChoices[InstrumentationLocation::INSTRUCTION_PRE])
- if (IO->Enabled)
+ if (IO->getEnabled())
RegisterForAllOpcodes(InstChoicesPRE, IO);
for (auto &[Name, IO] :
IConf.IChoices[InstrumentationLocation::INSTRUCTION_POST])
- if (IO->Enabled)
+ if (IO->getEnabled())
RegisterForAllOpcodes(InstChoicesPOST, IO);
Changed |= instrumentModule();
@@ -692,7 +692,7 @@ InstrumentationConfig::getBasePointerInfo(Value &V,
auto *BPIO =
IChoices[InstrumentationLocation::SPECIAL_VALUE]["base_pointer_info"];
- if (!BPIO || !BPIO->Enabled) {
+ if (!BPIO || !BPIO->getEnabled()) {
IIRB.Ctx.diagnose(DiagnosticInfoInstrumentation(
"Base pointer info disabled but required, passing nullptr.",
DS_Warning));
diff --git a/llvm/lib/Transforms/IPO/InstrumentorConfigFile.cpp b/llvm/lib/Transforms/IPO/InstrumentorConfigFile.cpp
index 083eca05b00f4..617e1bb6dca4a 100644
--- a/llvm/lib/Transforms/IPO/InstrumentorConfigFile.cpp
+++ b/llvm/lib/Transforms/IPO/InstrumentorConfigFile.cpp
@@ -96,7 +96,7 @@ void writeConfigToJSON(InstrumentationConfig &IConf, StringRef OutputFile,
for (auto &[Name, Choice] : KindChoices) {
J.attributeBegin(Name);
J.objectBegin();
- J.attribute("enabled", Choice->Enabled);
+ J.attribute("enabled", Choice->getEnabled());
J.attribute("filter", Choice->Filter);
J.attribute("filter.description",
"Static property filter to exclude instrumentation.");
@@ -292,7 +292,7 @@ bool readConfigFromJSON(InstrumentationConfig &IConf, StringRef InputFile,
Ctx.diagnose(DiagnosticInfoInstrumentation(Diag, DS_Warning));
}
}
- IO->Enabled = ValueMap["enabled"];
+ IO->setEnabled(ValueMap["enabled"]);
IO->Filter = FilterStr;
for (auto &IRArg : IO->IRTArgs) {
IRArg.Enabled = ValueMap[IRArg.Name];
@@ -307,7 +307,7 @@ bool readConfigFromJSON(InstrumentationConfig &IConf, StringRef InputFile,
for (auto &IChoiceMap : IConf.IChoices)
for (auto &It : IChoiceMap)
if (!SeenIOs.count(It.second))
- It.second->Enabled = false;
+ It.second->setEnabled(false);
return true;
}
diff --git a/llvm/lib/Transforms/IPO/InstrumentorStubPrinter.cpp b/llvm/lib/Transforms/IPO/InstrumentorStubPrinter.cpp
index a2c5c7660e61f..b2e8a72064e32 100644
--- a/llvm/lib/Transforms/IPO/InstrumentorStubPrinter.cpp
+++ b/llvm/lib/Transforms/IPO/InstrumentorStubPrinter.cpp
@@ -310,7 +310,7 @@ void printRuntimeStub(const InstrumentationConfig &IConf,
for (auto &ChoiceMap : IConf.IChoices) {
for (auto &[_, IO] : ChoiceMap) {
- if (!IO->Enabled)
+ if (!IO->getEnabled())
continue;
IRTCallDescription IRTCallDesc(*IO, IO->getRetTy(Ctx));
const auto Signatures = IRTCallDesc.createCSignature(IConf);
diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
index 119b32aee2e8e..180eb66bee992 100644
--- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
+++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
@@ -18,6 +18,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO/OpenMPOpt.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/EnumeratedArray.h"
@@ -353,13 +354,14 @@ struct OMPInformationCache : public InformationCache {
StringRef Name;
/// Flag to indicate a variadic function.
- bool IsVarArg;
+ bool getIsVarArg() const { return ArgumentTypes.getFlag(0); }
+ void setIsVarArg(bool Value) { ArgumentTypes.setFlag(0, Value); }
/// The return type of the function.
Type *ReturnType;
/// The argument types of the function.
- SmallVector<Type *, 8> ArgumentTypes;
+ llvm::SmallVectorWithFlags<Type *, 8> ArgumentTypes;
/// The declaration if available.
Function *Declaration = nullptr;
@@ -669,9 +671,9 @@ struct OMPInformationCache : public InformationCache {
auto &RFI = RFIs[_Enum]; \
RFI.Kind = _Enum; \
RFI.Name = _Name; \
- RFI.IsVarArg = _IsVarArg; \
+ RFI.setIsVarArg(_IsVarArg); \
RFI.ReturnType = OMPBuilder._ReturnType; \
- RFI.ArgumentTypes = std::move(ArgsTypes); \
+ RFI.ArgumentTypes.assign(std::move(ArgsTypes)); \
RFI.Declaration = F; \
unsigned NumUses = collectUses(RFI); \
(void)NumUses; \
diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp
index 2d45578071d89..852f1473c8039 100644
--- a/llvm/lib/Transforms/IPO/PartialInlining.cpp
+++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
@@ -244,11 +245,14 @@ struct PartialInlinerImpl {
typedef std::pair<Function *, BasicBlock *> FuncBodyCallerPair;
// Keep track of Outlined Functions and the basic block they're called from.
- SmallVector<FuncBodyCallerPair, 4> OutlinedFunctions;
+ llvm::SmallVectorWithFlags<FuncBodyCallerPair, 4> OutlinedFunctions;
// ClonedFunc is inlined in one of its callers after function
// outlining.
- bool IsFunctionInlined = false;
+ bool getIsFunctionInlined() const { return OutlinedFunctions.getFlag(0); }
+ void setIsFunctionInlined(bool Value) {
+ OutlinedFunctions.setFlag(0, Value);
+ }
// The cost of the region to be outlined.
InstructionCost OutlinedRegionCost = 0;
// ClonedOI is specific to outlining non-early return blocks.
@@ -1220,7 +1224,7 @@ PartialInlinerImpl::FunctionCloner::~FunctionCloner() {
// users (function pointers, etc.) back to the original function.
ClonedFunc->replaceAllUsesWith(OrigFunc);
ClonedFunc->eraseFromParent();
- if (!IsFunctionInlined) {
+ if (!getIsFunctionInlined()) {
// Remove each function that was speculatively created if there is no
// reference.
for (auto FuncBBPair : OutlinedFunctions) {
@@ -1410,7 +1414,7 @@ bool PartialInlinerImpl::tryPartialInline(FunctionCloner &Cloner) {
}
if (AnyInline) {
- Cloner.IsFunctionInlined = true;
+ Cloner.setIsFunctionInlined(true);
if (CalleeEntryCount)
Cloner.OrigFunc->setEntryCount(CalleeEntryCountV);
OptimizationRemarkEmitter OrigFuncORE(Cloner.OrigFunc);
diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp
index 7bef602c3e2c3..4efac84767738 100644
--- a/llvm/lib/Transforms/IPO/SampleProfile.cpp
+++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp
@@ -1243,7 +1243,7 @@ bool SampleProfileLoader::tryInlineCandidate(
return false;
InlineFunctionInfo IFI(GetAC);
- IFI.UpdateProfile = false;
+ IFI.setUpdateProfile(false);
InlineResult IR = InlineFunction(CB, IFI,
/*MergeAttributes=*/true);
if (!IR.isSuccess())
diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
index 88c57d2195bbd..50926ab59277e 100644
--- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -67,6 +67,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
@@ -587,7 +588,9 @@ struct DevirtModule {
/// when multiple unique return values occur in the same vtable.
ArrayType *const Int8Arr0Ty;
- const bool RemarksEnabled;
+ bool getRemarksEnabled() const {
+ return CallsWithPtrAuthBundleRemoved.getFlag(0);
+ }
std::function<OptimizationRemarkEmitter &(Function &)> OREGetter;
MapVector<VTableSlot, VTableSlotInfo> CallSlots;
@@ -598,7 +601,7 @@ struct DevirtModule {
// Store calls that had their ptrauth bundle removed. They are to be deleted
// at the end of the optimization.
- SmallVector<CallBase *, 8> CallsWithPtrAuthBundleRemoved;
+ llvm::SmallVectorWithFlags<CallBase *, 8, 2> CallsWithPtrAuthBundleRemoved;
// This map keeps track of the number of "unsafe" uses of a loaded function
// pointer. The key is the associated llvm.type.test intrinsic call generated
@@ -611,7 +614,9 @@ struct DevirtModule {
std::map<CallInst *, unsigned> NumUnsafeUsesForTypeTest;
PatternList FunctionsToSkip;
- const bool DevirtSpeculatively;
+ bool getDevirtSpeculatively() const {
+ return CallsWithPtrAuthBundleRemoved.getFlag(1);
+ }
DevirtModule(Module &M, ModuleAnalysisManager &MAM,
ModuleSummaryIndex *ExportSummary,
const ModuleSummaryIndex *ImportSummary,
@@ -625,11 +630,13 @@ struct DevirtModule {
Int64Ty(Type::getInt64Ty(M.getContext())),
IntPtrTy(M.getDataLayout().getIntPtrType(M.getContext(), 0)),
Int8Arr0Ty(ArrayType::get(Type::getInt8Ty(M.getContext()), 0)),
- RemarksEnabled(areRemarksEnabled()),
OREGetter([&](Function &F) -> OptimizationRemarkEmitter & {
return FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
}),
- DevirtSpeculatively(DevirtSpeculatively) {
+ CallsWithPtrAuthBundleRemoved(
+ decltype(this->CallsWithPtrAuthBundleRemoved)::withFlags(
+ unsigned(bool(areRemarksEnabled())) |
+ (unsigned(DevirtSpeculatively) << 1))) {
assert(!(ExportSummary && ImportSummary));
FunctionsToSkip.init(SkipFunctionNames);
}
@@ -1111,8 +1118,8 @@ bool DevirtModule::tryFindVirtualCallTargets(
// Without DevirtSpeculatively, we cannot perform whole program
// devirtualization analysis on a vtable with public LTO visibility.
- if (!DevirtSpeculatively && TM.Bits->GV->getVCallVisibility() ==
- GlobalObject::VCallVisibilityPublic)
+ if (!getDevirtSpeculatively() && TM.Bits->GV->getVCallVisibility() ==
+ GlobalObject::VCallVisibilityPublic)
return false;
Function *Fn = nullptr;
@@ -1133,7 +1140,7 @@ bool DevirtModule::tryFindVirtualCallTargets(
// In most cases empty functions will be overridden by the
// implementation of the derived class, so we can skip them.
- if (DevirtSpeculatively && Fn->getReturnType()->isVoidTy() &&
+ if (getDevirtSpeculatively() && Fn->getReturnType()->isVoidTy() &&
Fn->getInstructionCount() <= 1)
continue;
@@ -1228,7 +1235,7 @@ void DevirtModule::applySingleImplDevirt(VTableSlotInfo &SlotInfo,
if (!DebugCounter::shouldExecute(CallsToDevirt))
continue;
- if (RemarksEnabled)
+ if (getRemarksEnabled())
VCallSite.emitRemark("single-impl",
TheFn->stripPointerCasts()->getName(), OREGetter);
NumSingleImpl++;
@@ -1257,7 +1264,8 @@ void DevirtModule::applySingleImplDevirt(VTableSlotInfo &SlotInfo,
// add support to compare the virtual function pointer to the
// devirtualized target. In case of a mismatch, fall back to indirect
// call.
- if (DevirtCheckMode == WPDCheckMode::Fallback || DevirtSpeculatively) {
+ if (DevirtCheckMode == WPDCheckMode::Fallback ||
+ getDevirtSpeculatively()) {
MDNode *Weights = MDBuilder(M.getContext()).createLikelyBranchWeights();
// Version the indirect call site. If the called value is equal to the
// given callee, 'NewInst' will be executed, otherwise the original call
@@ -1347,7 +1355,7 @@ bool DevirtModule::trySingleImplDevirt(
return false;
// If so, update each call site to call that implementation directly.
- if (RemarksEnabled || AreStatisticsEnabled())
+ if (getRemarksEnabled() || AreStatisticsEnabled())
TargetsForSlot[0].WasDevirt = true;
bool IsExported = false;
@@ -1559,7 +1567,7 @@ void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
continue;
NumBranchFunnel++;
- if (RemarksEnabled)
+ if (getRemarksEnabled())
VCallSite.emitRemark("branch-funnel", JT.getName(), OREGetter);
// Pass the address of the vtable in the nest register, which is r10 on
@@ -1682,7 +1690,7 @@ void DevirtModule::applyUniformRetValOpt(CallSiteInfo &CSInfo, StringRef FnName,
continue;
NumUniformRetVal++;
Call.replaceAndErase(
- "uniform-ret-val", FnName, RemarksEnabled, OREGetter,
+ "uniform-ret-val", FnName, getRemarksEnabled(), OREGetter,
ConstantInt::get(cast<IntegerType>(Call.CB.getType()), TheRetVal));
}
CSInfo.markDevirt();
@@ -1704,7 +1712,7 @@ bool DevirtModule::tryUniformRetValOpt(
}
applyUniformRetValOpt(CSInfo, TargetsForSlot[0].Fn->getName(), TheRetVal);
- if (RemarksEnabled || AreStatisticsEnabled())
+ if (getRemarksEnabled() || AreStatisticsEnabled())
for (auto &&Target : TargetsForSlot)
Target.WasDevirt = true;
return true;
@@ -1798,8 +1806,8 @@ void DevirtModule::applyUniqueRetValOpt(CallSiteInfo &CSInfo, StringRef FnName,
B.CreateBitCast(UniqueMemberAddr, Call.VTable->getType()));
Cmp = B.CreateZExt(Cmp, Call.CB.getType());
NumUniqueRetVal++;
- Call.replaceAndErase("unique-ret-val", FnName, RemarksEnabled, OREGetter,
- Cmp);
+ Call.replaceAndErase("unique-ret-val", FnName, getRemarksEnabled(),
+ OREGetter, Cmp);
}
CSInfo.markDevirt();
}
@@ -1841,7 +1849,7 @@ bool DevirtModule::tryUniqueRetValOpt(
UniqueMemberAddr);
// Update devirtualization statistics for targets.
- if (RemarksEnabled || AreStatisticsEnabled())
+ if (getRemarksEnabled() || AreStatisticsEnabled())
for (auto &&Target : TargetsForSlot)
Target.WasDevirt = true;
@@ -1870,12 +1878,12 @@ void DevirtModule::applyVirtualConstProp(CallSiteInfo &CSInfo, StringRef FnName,
Value *BitsAndBit = B.CreateAnd(Bits, Bit);
auto IsBitSet = B.CreateICmpNE(BitsAndBit, ConstantInt::get(Int8Ty, 0));
NumVirtConstProp1Bit++;
- Call.replaceAndErase("virtual-const-prop-1-bit", FnName, RemarksEnabled,
- OREGetter, IsBitSet);
+ Call.replaceAndErase("virtual-const-prop-1-bit", FnName,
+ getRemarksEnabled(), OREGetter, IsBitSet);
} else {
Value *Val = B.CreateLoad(RetType, Addr);
NumVirtConstProp++;
- Call.replaceAndErase("virtual-const-prop", FnName, RemarksEnabled,
+ Call.replaceAndErase("virtual-const-prop", FnName, getRemarksEnabled(),
OREGetter, Val);
}
}
@@ -2006,7 +2014,7 @@ bool DevirtModule::tryVirtualConstProp(
// have an aligned load.
assert(OffsetByte % TypeAlignment.value() == 0);
- if (RemarksEnabled || AreStatisticsEnabled())
+ if (getRemarksEnabled() || AreStatisticsEnabled())
for (auto &&Target : TargetsForSlot)
Target.WasDevirt = true;
@@ -2445,7 +2453,7 @@ bool DevirtModule::run() {
Function *PublicTypeTestFunc = nullptr;
// If we are in speculative devirtualization mode, we can work on the public
// type test intrinsics.
- if (DevirtSpeculatively)
+ if (getDevirtSpeculatively())
PublicTypeTestFunc =
Intrinsic::getDeclarationIfExists(&M, Intrinsic::public_type_test);
Function *TypeTestFunc =
@@ -2581,7 +2589,7 @@ bool DevirtModule::run() {
// Out of speculative devirtualization mode, Try to apply virtual constant
// propagation or branch funneling.
// TODO: This should eventually be enabled for non-public type tests.
- if (!SingleImplDevirt && !DevirtSpeculatively) {
+ if (!SingleImplDevirt && !getDevirtSpeculatively()) {
DidVirtualConstProp |=
tryVirtualConstProp(TargetsForSlot, S.second, Res, S.first);
@@ -2589,7 +2597,7 @@ bool DevirtModule::run() {
}
// Collect functions devirtualized at least for one call site for stats.
- if (RemarksEnabled || AreStatisticsEnabled())
+ if (getRemarksEnabled() || AreStatisticsEnabled())
for (const auto &T : TargetsForSlot)
if (T.WasDevirt)
DevirtTargets[std::string(T.Fn->getName())] = T.Fn;
@@ -2613,7 +2621,7 @@ bool DevirtModule::run() {
}
}
- if (RemarksEnabled) {
+ if (getRemarksEnabled()) {
// Generate remarks for each devirtualized function.
for (const auto &DT : DevirtTargets) {
GlobalValue *GV = DT.second;
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 8de58841938a8..d81e5dc9deaab 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -22,6 +22,7 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -462,22 +463,26 @@ namespace {
/// required funclet OpBundle.
class RuntimeCallInserter {
Function *OwnerFn = nullptr;
- bool TrackInsertedCalls = false;
- SmallVector<CallInst *> InsertedCalls;
+ bool getTrackInsertedCalls() const { return InsertedCalls.getFlag(0); }
+ bool setTrackInsertedCalls(bool Value) {
+ InsertedCalls.setFlag(0, Value);
+ return Value;
+ }
+ llvm::SmallVectorWithFlags<CallInst *> InsertedCalls;
public:
RuntimeCallInserter(Function &Fn) : OwnerFn(&Fn) {
if (Fn.hasPersonalityFn()) {
auto Personality = classifyEHPersonality(Fn.getPersonalityFn());
if (isScopedEHPersonality(Personality))
- TrackInsertedCalls = true;
+ setTrackInsertedCalls(true);
}
}
~RuntimeCallInserter() {
if (InsertedCalls.empty())
return;
- assert(TrackInsertedCalls && "Calls were wrongly tracked");
+ assert(getTrackInsertedCalls() && "Calls were wrongly tracked");
DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(*OwnerFn);
for (CallInst *CI : InsertedCalls) {
@@ -519,7 +524,7 @@ class RuntimeCallInserter {
assert(IRB.GetInsertBlock()->getParent() == OwnerFn);
CallInst *Inst = IRB.CreateCall(Callee, Args, Name, nullptr);
- if (TrackInsertedCalls)
+ if (getTrackInsertedCalls())
InsertedCalls.push_back(Inst);
return Inst;
}
@@ -833,13 +838,16 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
SmallVector<AllocaPoisonCall, 8> StaticAllocaPoisonCallVec;
SmallVector<AllocaInst *, 1> DynamicAllocaVec;
- SmallVector<IntrinsicInst *, 1> StackRestoreVec;
+ llvm::SmallVectorWithFlags<IntrinsicInst *, 1, 3> StackRestoreVec;
AllocaInst *DynamicAllocaLayout = nullptr;
IntrinsicInst *LocalEscapeCall = nullptr;
- bool HasInlineAsm = false;
- bool HasReturnsTwiceCall = false;
- bool PoisonStack;
+ bool getHasInlineAsm() const { return StackRestoreVec.getFlag(0); }
+ void setHasInlineAsm(bool Value) { StackRestoreVec.setFlag(0, Value); }
+ bool getHasReturnsTwiceCall() const { return StackRestoreVec.getFlag(1); }
+ void setHasReturnsTwiceCall(bool Value) { StackRestoreVec.setFlag(1, Value); }
+ bool getPoisonStack() const { return StackRestoreVec.getFlag(2); }
+ void setPoisonStack(bool Value) { StackRestoreVec.setFlag(2, Value); }
FunctionStackPoisoner(Function &F, AddressSanitizer &ASan,
RuntimeCallInserter &RTCI)
@@ -848,11 +856,13 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
IntptrTy(ASan.IntptrTy),
IntptrPtrTy(PointerType::get(IntptrTy->getContext(), 0)),
Mapping(ASan.Mapping),
- PoisonStack(Opts.asan_stack &&
- !F.getParent()->getTargetTriple().isAMDGPU()) {}
+ StackRestoreVec(decltype(this->StackRestoreVec)::withFlags(
+ (unsigned(bool(Opts.asan_stack &&
+ !F.getParent()->getTargetTriple().isAMDGPU()))
+ << 2))) {}
bool runOnFunction() {
- if (!PoisonStack)
+ if (!getPoisonStack())
return false;
if (Opts.asan_redzone_byval_args)
@@ -1000,8 +1010,16 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
void visitCallBase(CallBase &CB) {
if (CallInst *CI = dyn_cast<CallInst>(&CB)) {
- HasInlineAsm |= CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
- HasReturnsTwiceCall |= CI->canReturnTwice();
+ [&] {
+ auto PackedFlagValue =
+ CI->isInlineAsm() && &CB != ASan.LocalDynamicShadow;
+ return setHasInlineAsm(getHasInlineAsm() | PackedFlagValue);
+ }();
+ [&] {
+ auto PackedFlagValue = CI->canReturnTwice();
+ return setHasReturnsTwiceCall(getHasReturnsTwiceCall() |
+ PackedFlagValue);
+ }();
}
}
@@ -1362,7 +1380,8 @@ void AddressSanitizer::getInterestingMemoryOperands(
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
MemIntrinsicInfo IntrInfo;
if (TTI->getTgtMemIntrinsic(II, IntrInfo))
- Interesting = IntrInfo.InterestingOperands;
+ Interesting.assign(IntrInfo.InterestingOperands.begin(),
+ IntrInfo.InterestingOperands.end());
return;
}
for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
@@ -3456,8 +3475,8 @@ void FunctionStackPoisoner::processStaticAllocas() {
// 2) There is a returns_twice call (typically setjmp), which is
// optimization-hostile, and doesn't play well with introduced indirect
// register-relative calculation of local variable addresses.
- DoDynamicAlloca &= !HasInlineAsm && !HasReturnsTwiceCall;
- DoStackMalloc &= !HasInlineAsm && !HasReturnsTwiceCall;
+ DoDynamicAlloca &= !getHasInlineAsm() && !getHasReturnsTwiceCall();
+ DoStackMalloc &= !getHasInlineAsm() && !getHasReturnsTwiceCall();
Type *PtrTy = F.getDataLayout().getAllocaPtrType(F.getContext());
Value *StaticAlloca =
diff --git a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
index d4e6a6936bbcc..bfe8348bc45c2 100644
--- a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
+++ b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/GlobalsModRef.h"
@@ -110,8 +111,9 @@ struct RegInfo {
RegInfo() = default;
RegInfo(Region *RegionIn) : R(RegionIn) {}
Region *R = nullptr;
- bool HasBranch = false;
- SmallVector<SelectInst *, 8> Selects;
+ bool getHasBranch() const { return Selects.getFlag(0); }
+ void setHasBranch(bool Value) { Selects.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<SelectInst *, 8> Selects;
};
typedef DenseMap<Region *, DenseSet<Instruction *>> HoistStopMapTy;
@@ -424,7 +426,7 @@ void CHRScope::print(raw_ostream &OS) const {
OS << RegInfos.size() << ", Regions[";
for (const RegInfo &RI : RegInfos) {
OS << RI.R->getNameStr();
- if (RI.HasBranch)
+ if (RI.getHasBranch())
OS << " B";
if (RI.Selects.size() > 0)
OS << " S" << RI.Selects.size();
@@ -760,14 +762,14 @@ CHRScope * CHR::findScope(Region *R) {
CHR_DEBUG(dbgs() << "S1 " << S1->getName() << "\n");
if (S0 != S1 && (S0 == Exit || S1 == Exit)) {
RegInfo RI(R);
- RI.HasBranch =
- checkBiasedBranch(Opts, BI, R, TrueBiasedRegionsGlobal,
- FalseBiasedRegionsGlobal, BranchBiasMap);
+ RI.setHasBranch(checkBiasedBranch(Opts, BI, R, TrueBiasedRegionsGlobal,
+ FalseBiasedRegionsGlobal,
+ BranchBiasMap));
Result = new CHRScope(RI);
Scopes.insert(Result);
CHR_DEBUG(dbgs() << "Found a region with a branch\n");
++Stats.NumBranches;
- if (!RI.HasBranch) {
+ if (!RI.getHasBranch()) {
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "BranchNotBiased", BI)
<< "Branch not biased";
@@ -863,9 +865,9 @@ void CHR::checkScopeHoistable(CHRScope *Scope) {
Region *R = RI.R;
BasicBlock *EntryBB = R->getEntry();
auto *Branch =
- RI.HasBranch ? cast<CondBrInst>(EntryBB->getTerminator()) : nullptr;
- SmallVector<SelectInst *, 8> &Selects = RI.Selects;
- if (RI.HasBranch || !Selects.empty()) {
+ RI.getHasBranch() ? cast<CondBrInst>(EntryBB->getTerminator()) : nullptr;
+ auto &Selects = RI.Selects;
+ if (RI.getHasBranch() || !Selects.empty()) {
Instruction *InsertPoint = getBranchInsertPoint(RI);
CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
// Avoid a data dependence from a select or a branch to a(nother)
@@ -900,7 +902,7 @@ void CHR::checkScopeHoistable(CHRScope *Scope) {
// Update InsertPoint after potentially removing selects.
InsertPoint = getBranchInsertPoint(RI);
CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
- if (RI.HasBranch && InsertPoint != Branch) {
+ if (RI.getHasBranch() && InsertPoint != Branch) {
DenseMap<Instruction *, bool> Visited;
bool IsHoistable = checkHoistValue(Branch->getCondition(), InsertPoint,
DT, Unhoistables, nullptr, Visited);
@@ -930,7 +932,7 @@ void CHR::checkScopeHoistable(CHRScope *Scope) {
}
CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
#ifndef NDEBUG
- if (RI.HasBranch) {
+ if (RI.getHasBranch()) {
assert(!DT.dominates(Branch, InsertPoint) &&
"Branch can't be already above the hoist point");
DenseMap<Instruction *, bool> Visited;
@@ -947,7 +949,7 @@ void CHR::checkScopeHoistable(CHRScope *Scope) {
"checkHoistValue for selects");
}
CHR_DEBUG(dbgs() << "Result\n");
- if (RI.HasBranch) {
+ if (RI.getHasBranch()) {
CHR_DEBUG(dbgs() << "BI " << *Branch << "\n");
}
for (auto *SI : Selects) {
@@ -1009,7 +1011,7 @@ CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
static DenseSet<Value *> getCHRConditionValuesForRegion(RegInfo &RI) {
DenseSet<Value *> ConditionValues;
- if (RI.HasBranch) {
+ if (RI.getHasBranch()) {
auto *BI = cast<CondBrInst>(RI.R->getEntry()->getTerminator());
ConditionValues.insert(BI->getCondition());
}
@@ -1272,7 +1274,7 @@ void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
for (RegInfo &RI : Scope->RegInfos) {
- if (RI.HasBranch) {
+ if (RI.getHasBranch()) {
Region *R = RI.R;
if (TrueBiasedRegionsGlobal.contains(R))
OutermostScope->TrueBiasedRegions.insert(R);
@@ -1363,7 +1365,7 @@ void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
Region *R = RI.R;
DenseSet<Instruction *> HoistStops;
bool IsHoisted = false;
- if (RI.HasBranch) {
+ if (RI.getHasBranch()) {
assert((OutermostScope->TrueBiasedRegions.contains(R) ||
OutermostScope->FalseBiasedRegions.contains(R)) &&
"Must be truthy or falsy");
@@ -1466,7 +1468,7 @@ static void hoistScopeConditions(CHRScope *Scope, Instruction *HoistPoint,
Region *R = RI.R;
bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
- if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
+ if (RI.getHasBranch() && (IsTrueBiased || IsFalseBiased)) {
auto *BI = cast<CondBrInst>(R->getEntry()->getTerminator());
hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
HoistedSet, TrivialPHIs, DT);
@@ -1641,7 +1643,7 @@ assertBranchOrSelectConditionHoisted(CHRScope *Scope,
Region *R = RI.R;
bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
- if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
+ if (RI.getHasBranch() && (IsTrueBiased || IsFalseBiased)) {
auto *BI = cast<CondBrInst>(R->getEntry()->getTerminator());
Value *V = BI->getCondition();
CHR_DEBUG(dbgs() << *V << "\n");
@@ -1862,7 +1864,7 @@ void CHR::fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
IRBuilder<> IRB(PreEntryBlock->getTerminator());
for (RegInfo &RI : Scope->CHRRegions) {
Region *R = RI.R;
- if (RI.HasBranch) {
+ if (RI.getHasBranch()) {
fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
++NumCHRedBranches;
}
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index ea31e08a4661a..ead13eba80a57 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -1382,7 +1382,7 @@ void HWAddressSanitizer::instrumentStack(OptimizationRemarkEmitter &ORE,
// postdominator analysis, and will leave us to keep memory tagged after
// function return. Work around this by always untagging at every return
// statement if return_twice functions are called.
- if (DetectUseAfterScope && !SInfo.CallsReturnTwice &&
+ if (DetectUseAfterScope && !SInfo.getCallsReturnTwice() &&
memtag::isSupportedLifetime(Info, &DT, &LI)) {
TagStarts();
memtag::forAllReachableExits(DT, PDT, LI, Info, SInfo.RetVec, TagEnd);
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 6a7bda565ef21..8ee3e351d51d0 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
@@ -426,8 +427,9 @@ class PGOCounterPromoter {
const InstrumentationOptions &Opts,
DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCands,
Loop &CurLoop, LoopInfo &LI, BlockFrequencyInfo *BFI, bool IsAtomic)
- : Opts(Opts), LoopToCandidates(LoopToCands), L(CurLoop), LI(LI), BFI(BFI),
- IsAtomic(IsAtomic) {
+ : Opts(Opts), LoopToCandidates(LoopToCands),
+ InsertPts(decltype(this->InsertPts)::withFlags(unsigned(IsAtomic))),
+ L(CurLoop), LI(LI), BFI(BFI) {
// Skip collection of ExitBlocks and InsertPts for loops that will not be
// able to have counters promoted.
@@ -468,7 +470,7 @@ class PGOCounterPromoter {
// 3) convert all (promoted and unpromotable) updates to atomicRMW.
// This requires that promoted candidates are set to nullptr in the
// Candidates array by the promoteCandidates() function.
- if (IsAtomic)
+ if (getIsAtomic())
for (auto &Cand : Candidates)
if (Cand.first != nullptr && Cand.second != nullptr)
makeAtomic(Cand.first, Cand.second);
@@ -518,7 +520,7 @@ class PGOCounterPromoter {
PGOCounterPromoterHelper Promoter(
Opts, Cand.first, Cand.second, SSA, InitVal, L.getLoopPreheader(),
- ExitBlocks, InsertPts, LoopToCandidates, LI, IsAtomic);
+ ExitBlocks, InsertPts, LoopToCandidates, LI, getIsAtomic());
Promoter.run(SmallVector<Instruction *, 2>({Cand.first, Cand.second}));
Cand = {nullptr, nullptr};
@@ -614,11 +616,13 @@ class PGOCounterPromoter {
const InstrumentationOptions &Opts;
DenseMap<Loop *, SmallVector<LoadStorePair, 8>> &LoopToCandidates;
SmallVector<BasicBlock *, 8> ExitBlocks;
- SmallVector<Instruction *, 8> InsertPts;
+ llvm::SmallVectorWithFlags<Instruction *, 8> InsertPts;
Loop &L;
LoopInfo &LI;
BlockFrequencyInfo *BFI;
- const bool IsAtomic; // Whether to convert counter updates to atomics.
+ bool getIsAtomic() const {
+ return InsertPts.getFlag(0);
+ } // Whether to convert counter updates to atomics.
};
enum class ValueProfilingCallType {
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 2e31d692599cf..630b4d7ddb1f2 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -157,6 +157,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/GlobalsModRef.h"
@@ -1046,11 +1047,18 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// The following flags disable parts of MSan instrumentation based on
// exclusion list contents and command-line options.
- bool InsertChecks;
- bool PropagateShadow;
- bool PoisonStack;
- bool PoisonUndef;
- bool PoisonUndefVectors;
+ bool getInsertChecks() const { return StoreList.getFlag(0); }
+ void setInsertChecks(bool Value) { StoreList.setFlag(0, Value); }
+ bool getPropagateShadow() const { return StoreList.getFlag(1); }
+ void setPropagateShadow(bool Value) { StoreList.setFlag(1, Value); }
+ bool getPoisonStack() const { return StoreList.getFlag(2); }
+ void setPoisonStack(bool Value) { StoreList.setFlag(2, Value); }
+ bool getPoisonUndef() const { return StoreList.getFlag(3); }
+ void setPoisonUndef(bool Value) { StoreList.setFlag(3, Value); }
+ bool getPoisonUndefVectors() const { return LifetimeStartList.getFlag(0); }
+ void setPoisonUndefVectors(bool Value) {
+ LifetimeStartList.setFlag(0, Value);
+ }
struct ShadowOriginAndInsertPoint {
Value *Shadow;
@@ -1063,8 +1071,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
SmallVector<ShadowOriginAndInsertPoint, 16> InstrumentationList;
DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
SmallSetVector<AllocaInst *, 16> AllocaSet;
- SmallVector<std::pair<IntrinsicInst *, AllocaInst *>, 16> LifetimeStartList;
- SmallVector<StoreInst *, 16> StoreList;
+ llvm::SmallVectorWithFlags<std::pair<IntrinsicInst *, AllocaInst *>, 16>
+ LifetimeStartList;
+ llvm::SmallVectorWithFlags<StoreInst *, 16, 4> StoreList;
int64_t SplittableBlocksCount = 0;
MemorySanitizerVisitor(Function &F, MemorySanitizer &MS,
@@ -1073,11 +1082,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
TLI(&TLI) {
bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeMemory) &&
!Opts.msan_disable_checks;
- InsertChecks = SanitizeFunction;
- PropagateShadow = SanitizeFunction;
- PoisonStack = SanitizeFunction && Opts.msan_poison_stack;
- PoisonUndef = SanitizeFunction && Opts.msan_poison_undef;
- PoisonUndefVectors = SanitizeFunction && Opts.msan_poison_undef_vectors;
+ setInsertChecks(SanitizeFunction);
+ setPropagateShadow(SanitizeFunction);
+ setPoisonStack(SanitizeFunction && Opts.msan_poison_stack);
+ setPoisonUndef(SanitizeFunction && Opts.msan_poison_undef);
+ setPoisonUndefVectors(SanitizeFunction && Opts.msan_poison_undef_vectors);
// In the presence of unreachable blocks, we may see Phi nodes with
// incoming nodes from such blocks. Since InstVisitor skips unreachable
@@ -1095,7 +1104,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
insertKmsanPrologue(IRB);
}
- LLVM_DEBUG(if (!InsertChecks) dbgs()
+ LLVM_DEBUG(if (!getInsertChecks()) dbgs()
<< "MemorySanitizer is not inserting checks into '"
<< F.getName() << "'\n");
}
@@ -1834,7 +1843,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
"setShadow called with mismatching types");
}
- ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
+ ShadowMap[V] = getPropagateShadow() ? SV : getCleanShadow(V);
}
/// Set Origin to be the origin value for V.
@@ -1895,7 +1904,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
/// or extracts if from ParamTLS (for function arguments).
Value *getShadow(Value *V) {
if (Instruction *I = dyn_cast<Instruction>(V)) {
- if (!PropagateShadow || I->getMetadata(LLVMContext::MD_nosanitize))
+ if (!getPropagateShadow() || I->getMetadata(LLVMContext::MD_nosanitize))
return getCleanShadow(V);
// For instructions the shadow is already stored in the map.
Value *Shadow = ShadowMap[V];
@@ -1908,8 +1917,9 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// Handle fully undefined values
// (partially undefined constant vectors are handled later)
if ([[maybe_unused]] UndefValue *U = dyn_cast<UndefValue>(V)) {
- Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
- : getCleanShadow(V);
+ Value *AllOnes = (getPropagateShadow() && getPoisonUndef())
+ ? getPoisonedShadow(V)
+ : getCleanShadow(V);
LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n");
return AllOnes;
}
@@ -1951,7 +1961,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
std::tie(CpShadowPtr, CpOriginPtr) =
getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
/*isStore*/ true);
- if (!PropagateShadow || Overflow) {
+ if (!getPropagateShadow() || Overflow) {
// ParamTLS overflow.
EntryIRB.CreateMemSet(
CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()),
@@ -1977,7 +1987,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
}
}
- if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
+ if (!getPropagateShadow() || Overflow || FArg.hasByValAttr() ||
(MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
ShadowPtr = getCleanShadow(V);
setOrigin(A, getCleanOrigin());
@@ -2005,8 +2015,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// Check for partially-undefined constant vectors
// TODO: scalable vectors (this is hard because we do not have IRBuilder)
if (isa<FixedVectorType>(V->getType()) && isa<Constant>(V) &&
- cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
- PoisonUndefVectors) {
+ cast<Constant>(V)->containsUndefOrPoisonElement() &&
+ getPropagateShadow() && getPoisonUndefVectors()) {
unsigned NumElems = cast<FixedVectorType>(V->getType())->getNumElements();
SmallVector<Constant *, 32> ShadowVector(NumElems);
for (unsigned i = 0; i != NumElems; ++i) {
@@ -2037,7 +2047,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
Value *getOrigin(Value *V) {
if (!MS.TrackOrigins)
return nullptr;
- if (!PropagateShadow || isa<Constant>(V) || isa<InlineAsm>(V))
+ if (!getPropagateShadow() || isa<Constant>(V) || isa<InlineAsm>(V))
return getCleanOrigin();
assert((isa<Instruction>(V) || isa<Argument>(V)) &&
"Unexpected value type in getOrigin()");
@@ -2061,7 +2071,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
/// UMR warning in runtime if the shadow value is not 0.
void insertCheckShadow(Value *Shadow, Value *Origin, Instruction *OrigIns) {
assert(Shadow);
- if (!InsertChecks)
+ if (!getInsertChecks())
return;
if (!DebugCounter::shouldExecute(DebugInsertCheck)) {
@@ -2207,7 +2217,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
Value *Addr = I.getPointerOperand();
Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
const Align Alignment = I.getAlign();
- if (PropagateShadow) {
+ if (getPropagateShadow()) {
std::tie(ShadowPtr, OriginPtr) =
getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
setShadow(&I,
@@ -2223,7 +2233,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
I.setOrdering(addAcquireOrdering(I.getOrdering()));
if (MS.TrackOrigins) {
- if (PropagateShadow) {
+ if (getPropagateShadow()) {
const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
setOrigin(
&I, IRB.CreateAlignedLoad(MS.OriginTy, OriginPtr, OriginAlignment));
@@ -3306,7 +3316,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
Type *ShadowTy = getShadowTy(&I);
Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
- if (PropagateShadow) {
+ if (getPropagateShadow()) {
// We don't know the pointer alignment (could be unaligned SSE load!).
// Have to assume to worst case.
const Align Alignment = Align(1);
@@ -3322,7 +3332,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
insertCheckShadowOf(Addr, &I);
if (MS.TrackOrigins) {
- if (PropagateShadow)
+ if (getPropagateShadow())
setOrigin(&I, IRB.CreateLoad(MS.OriginTy, OriginPtr));
else
setOrigin(&I, getCleanOrigin());
@@ -3425,7 +3435,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
}
void handleLifetimeStart(IntrinsicInst &I) {
- if (!PoisonStack)
+ if (!getPoisonStack())
return;
AllocaInst *AI = dyn_cast<AllocaInst>(I.getArgOperand(0));
if (AI)
@@ -4318,7 +4328,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
}
void handleLdmxcsr(IntrinsicInst &I) {
- if (!InsertChecks)
+ if (!getInsertChecks())
return;
IRBuilder<> IRB(&I);
@@ -4350,7 +4360,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
insertCheckShadowOf(Mask, &I);
}
- if (!PropagateShadow) {
+ if (!getPropagateShadow()) {
setShadow(&I, getCleanShadow(&I));
setOrigin(&I, getCleanOrigin());
return;
@@ -4410,7 +4420,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &I);
}
- if (!PropagateShadow) {
+ if (!getPropagateShadow()) {
setShadow(&I, getCleanShadow(&I));
setOrigin(&I, getCleanOrigin());
return;
@@ -4507,7 +4517,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
insertCheckShadowOf(Mask, &I);
}
- if (!PropagateShadow) {
+ if (!getPropagateShadow()) {
setShadow(&I, getCleanShadow(&I));
setOrigin(&I, getCleanOrigin());
return;
@@ -4555,7 +4565,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
Mask, getShadow(Divisor), getCleanShadow(Divisor), "_msmaskeddivisor");
insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &I);
- if (!PropagateShadow) {
+ if (!getPropagateShadow()) {
setShadow(&I, getCleanShadow(&I));
setOrigin(&I, getCleanOrigin());
return;
@@ -7754,7 +7764,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
std::tie(AShadowPtr, AOriginPtr) =
getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
/*isStore*/ false);
- if (!PropagateShadow) {
+ if (!getPropagateShadow()) {
Store = IRB.CreateMemSet(ArgShadowBase,
Constant::getNullValue(IRB.getInt8Ty()),
Size, Alignment);
@@ -7891,7 +7901,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
void visitPHINode(PHINode &I) {
IRBuilder<> IRB(&I);
- if (!PropagateShadow) {
+ if (!getPropagateShadow()) {
setShadow(&I, getCleanShadow(&I));
setOrigin(&I, getCleanOrigin());
return;
@@ -7918,7 +7928,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
}
void poisonAllocaUserspace(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
- if (PoisonStack && Opts.msan_poison_stack_with_call) {
+ if (getPoisonStack() && Opts.msan_poison_stack_with_call) {
IRB.CreateCall(MS.MsanPoisonStackFn, {&I, Len});
} else {
Value *ShadowBase, *OriginBase;
@@ -7926,11 +7936,11 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
&I, IRB, IRB.getInt8Ty(), Align(1), /*isStore*/ true);
Value *PoisonValue =
- IRB.getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
+ IRB.getInt8(getPoisonStack() ? Opts.msan_poison_stack_pattern : 0);
IRB.CreateMemSet(ShadowBase, PoisonValue, Len, I.getAlign());
}
- if (PoisonStack && MS.TrackOrigins) {
+ if (getPoisonStack() && MS.TrackOrigins) {
Value *Idptr = getLocalVarIdptr(I);
if (Opts.msan_print_stack_names) {
Value *Descr = getLocalVarDescription(I);
@@ -7944,7 +7954,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
void poisonAllocaKmsan(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
Value *Descr = getLocalVarDescription(I);
- if (PoisonStack) {
+ if (getPoisonStack()) {
IRB.CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
} else {
IRB.CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
diff --git a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
index 03a79ac734f71..cf284cd5fd120 100644
--- a/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
@@ -36,6 +36,7 @@
#include "ScalarOptions.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -549,7 +550,7 @@ ConstantHoistingPass::maximizeConstantsInRange(ConstCandVecType::iterator S,
ConstCandVecType::iterator &MaxCostItr) {
unsigned NumUses = 0;
- if (!OptForSize || std::distance(S,E) > 100) {
+ if (!getOptForSize() || std::distance(S, E) > 100) {
for (auto ConstCand = S; ConstCand != E; ++ConstCand) {
NumUses += ConstCand->Uses.size();
if (ConstCand->CumulativeCost > MaxCostItr->CumulativeCost)
@@ -630,12 +631,17 @@ void ConstantHoistingPass::findAndMakeBaseConstant(
/// Finds and combines constant candidates that can be easily
/// rematerialized with an add from a common base constant.
void ConstantHoistingPass::findBaseConstants(GlobalVariable *BaseGV) {
+ ConstInfoVecType IntegerInfo;
+ IntegerInfo = std::move(ConstIntInfoVec);
+ auto RestoreIntegerInfo =
+ scope_exit([&] { ConstIntInfoVec.assign(std::move(IntegerInfo)); });
+
// If BaseGV is nullptr, find base among candidate constant integers;
// Otherwise find base among constant GEPs that share the same BaseGV.
ConstCandVecType &ConstCandVec = BaseGV ?
ConstGEPCandMap[BaseGV] : ConstIntCandVec;
- ConstInfoVecType &ConstInfoVec = BaseGV ?
- ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;
+ ConstInfoVecType &ConstInfoVec =
+ BaseGV ? ConstGEPInfoMap[BaseGV] : IntegerInfo;
// Sort the constants by value and type. This invalidates the mapping!
llvm::stable_sort(ConstCandVec, [](const ConstantCandidate &LHS,
@@ -811,9 +817,14 @@ void ConstantHoistingPass::emitBaseConstants(Instruction *Base,
/// Hoist and hide the base constant behind a bitcast and emit
/// materialization code for derived constants.
bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) {
+ ConstInfoVecType IntegerInfo;
+ IntegerInfo = std::move(ConstIntInfoVec);
+ auto RestoreIntegerInfo =
+ scope_exit([&] { ConstIntInfoVec.assign(std::move(IntegerInfo)); });
+
bool MadeChange = false;
SmallVectorImpl<consthoist::ConstantInfo> &ConstInfoVec =
- BaseGV ? ConstGEPInfoMap[BaseGV] : ConstIntInfoVec;
+ BaseGV ? ConstGEPInfoMap[BaseGV] : IntegerInfo;
for (const consthoist::ConstantInfo &ConstInfo : ConstInfoVec) {
SmallVector<BasicBlock::iterator, 4> MatInsertPts;
collectMatInsertPts(ConstInfo.RebasedConstants, MatInsertPts);
@@ -919,8 +930,8 @@ bool ConstantHoistingPass::runImpl(Function &Fn, TargetTransformInfo &TTI,
this->Ctx = &Fn.getContext();
this->Entry = &Entry;
this->PSI = PSI;
- this->OptForSize = llvm::shouldOptimizeForSize(Entry.getParent(), PSI, BFI,
- PGSOQueryType::IRPass);
+ this->setOptForSize(llvm::shouldOptimizeForSize(Entry.getParent(), PSI, BFI,
+ PGSOQueryType::IRPass));
// Collect all constant candidates.
collectConstantCandidates(Fn);
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 51c118e995096..15dd5c49ffa5d 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ConstraintSystem.h"
#include "llvm/Analysis/GlobalsModRef.h"
@@ -245,15 +246,16 @@ class ConstraintInfo;
struct StackEntry {
unsigned NumIn;
unsigned NumOut;
- bool IsSigned = false;
+ bool getIsSigned() const { return ValuesToRelease.getFlag(0); }
+ void setIsSigned(bool Value) { ValuesToRelease.setFlag(0, Value); }
/// Variables that can be removed from the system once the stack entry gets
/// removed.
- SmallVector<Value *, 2> ValuesToRelease;
+ llvm::SmallVectorWithFlags<Value *, 2> ValuesToRelease;
StackEntry(unsigned NumIn, unsigned NumOut, bool IsSigned,
SmallVector<Value *, 2> ValuesToRelease)
- : NumIn(NumIn), NumOut(NumOut), IsSigned(IsSigned),
- ValuesToRelease(std::move(ValuesToRelease)) {}
+ : NumIn(NumIn), NumOut(NumOut),
+ ValuesToRelease(unsigned(IsSigned), std::move(ValuesToRelease)) {}
};
struct ConstraintTy {
@@ -2138,12 +2140,12 @@ removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
SmallVectorImpl<StackEntry> &DFSInStack) {
Info.getDecomposeCache().clear();
- Info.popLastConstraint(E.IsSigned);
+ Info.popLastConstraint(E.getIsSigned());
// Remove variables in the system that went out of scope.
- auto &Mapping = Info.getValue2Index(E.IsSigned);
+ auto &Mapping = Info.getValue2Index(E.getIsSigned());
for (Value *V : E.ValuesToRelease)
Mapping.erase(V);
- Info.popLastNVariables(E.IsSigned, E.ValuesToRelease.size());
+ Info.popLastNVariables(E.getIsSigned(), E.ValuesToRelease.size());
DFSInStack.pop_back();
if (ReproducerModule)
ReproducerCondStack.pop_back();
@@ -2463,8 +2465,8 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
break;
LLVM_DEBUG({
dbgs() << "Removing ";
- dumpConstraint(Info.getCS(E.IsSigned).getLastConstraint(),
- Info.getValue2Index(E.IsSigned));
+ dumpConstraint(Info.getCS(E.getIsSigned()).getLastConstraint(),
+ Info.getValue2Index(E.getIsSigned()));
dbgs() << "\n";
});
removeEntryFromStack(E, Info, ReproducerModule.get(), ReproducerCondStack,
@@ -2716,7 +2718,7 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
#ifndef NDEBUG
unsigned SignedEntries =
- count_if(DFSInStack, [](const StackEntry &E) { return E.IsSigned; });
+ count_if(DFSInStack, [](const StackEntry &E) { return E.getIsSigned(); });
assert(Info.getCS(false).size() - FunctionArgs.size() ==
DFSInStack.size() - SignedEntries &&
"updates to CS and DFSInStack are out of sync");
diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 1266fd0708bfe..069f86a9a15df 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -38,6 +38,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -933,15 +934,26 @@ struct DSEState {
// Check if there are root nodes that are terminated by UnreachableInst.
// Those roots pessimize post-dominance queries. If there are such roots,
// fall back to CFG scan starting from all non-unreachable roots.
- bool AnyUnreachableExit;
+ bool getAnyUnreachableExit() const { return ToRemove.getFlag(0); }
+ bool setAnyUnreachableExit(bool Value) {
+ ToRemove.setFlag(0, Value);
+ return Value;
+ }
// Whether or not we should iterate on removing dead stores at the end of the
// function due to removing a store causing a previously captured pointer to
// no longer be captured.
- bool ShouldIterateEndOfFunctionDSE;
+ bool getShouldIterateEndOfFunctionDSE() const { return ToRemove.getFlag(1); }
+ bool setShouldIterateEndOfFunctionDSE(bool Value) {
+ ToRemove.setFlag(1, Value);
+ return Value;
+ }
/// Dead instructions to be removed at the end of DSE.
- SmallVector<Instruction *> ToRemove;
+ llvm::SmallVectorWithFlags<
+ Instruction *,
+ llvm::CalculateSmallVectorDefaultInlinedElements<Instruction *>::value, 2>
+ ToRemove;
// Class contains self-reference, make sure it's not copied/moved.
DSEState(const ScalarOptions &Opts, Function &F, AliasAnalysis &AA,
@@ -1163,9 +1175,9 @@ DSEState::DSEState(const ScalarOptions &Opts, Function &F, AliasAnalysis &AA,
InvisibleToCallerAfterRetBounded.insert({&AI, DeadBytes});
}
- AnyUnreachableExit = any_of(PDT.roots(), [](const BasicBlock *E) {
+ setAnyUnreachableExit(any_of(PDT.roots(), [](const BasicBlock *E) {
return isa<UnreachableInst>(E->getTerminator());
- });
+ }));
}
LocationSize DSEState::strengthenLocationSize(const Instruction *I,
@@ -1902,7 +1914,7 @@ std::optional<MemoryAccess *> DSEState::getDomMemoryDef(
// there is a path from MaybeDeadAccess to an exit not going through a
// killing block.
if (!PDT.dominates(CommonPred, MaybeDeadAccess->getBlock())) {
- if (!AnyUnreachableExit)
+ if (!getAnyUnreachableExit())
return std::nullopt;
// Fall back to CFG scan starting at all non-unreachable roots if not
@@ -1982,7 +1994,7 @@ void DSEState::deleteDeadInstruction(Instruction *SI,
if (SI->getValueOperand()->getType()->isPointerTy()) {
const Value *UO = getUnderlyingObject(SI->getValueOperand());
if (CapturedBeforeReturn.erase(UO))
- ShouldIterateEndOfFunctionDSE = true;
+ setShouldIterateEndOfFunctionDSE(true);
InvisibleToCallerAfterRet.erase(UO);
InvisibleToCallerAfterRetBounded.erase(UO);
}
@@ -2057,7 +2069,7 @@ bool DSEState::eliminateDeadWritesAtEndOfFunction() {
LLVM_DEBUG(
dbgs() << "Trying to eliminate MemoryDefs at the end of the function\n");
do {
- ShouldIterateEndOfFunctionDSE = false;
+ setShouldIterateEndOfFunctionDSE(false);
for (MemoryDef *Def : llvm::reverse(MemDefs)) {
if (SkipStores.contains(Def))
continue;
@@ -2088,7 +2100,7 @@ bool DSEState::eliminateDeadWritesAtEndOfFunction() {
MadeChange = true;
}
}
- } while (ShouldIterateEndOfFunctionDSE);
+ } while (getShouldIterateEndOfFunctionDSE());
return MadeChange;
}
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index ccd923cf7cc79..a015df31630cf 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -681,9 +681,9 @@ class EarlyCSE {
case Intrinsic::masked_load:
Info.PtrVal = Inst->getOperand(0);
Info.MatchingId = Intrinsic::masked_load;
- Info.ReadMem = true;
- Info.WriteMem = false;
- Info.IsVolatile = false;
+ Info.setReadMem(true);
+ Info.setWriteMem(false);
+ Info.setIsVolatile(false);
break;
case Intrinsic::masked_store:
Info.PtrVal = Inst->getOperand(1);
@@ -694,17 +694,17 @@ class EarlyCSE {
// 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;
+ Info.setReadMem(false);
+ Info.setWriteMem(true);
+ Info.setIsVolatile(false);
break;
}
} else if (auto *MI = dyn_cast<MemSetInst>(Inst)) {
Info.PtrVal = MI->getDest();
Info.MatchingId = 0;
- Info.ReadMem = false;
- Info.WriteMem = true;
- Info.IsVolatile = MI->isVolatile();
+ Info.setReadMem(false);
+ Info.setWriteMem(true);
+ Info.setIsVolatile(MI->isVolatile());
}
}
}
@@ -714,13 +714,13 @@ class EarlyCSE {
bool isLoad() const {
if (IntrID != 0)
- return Info.ReadMem;
+ return Info.getReadMem();
return isa<LoadInst>(Inst);
}
bool isStore() const {
if (IntrID != 0)
- return Info.WriteMem;
+ return Info.getWriteMem();
return isa<StoreInst>(Inst);
}
@@ -745,7 +745,7 @@ class EarlyCSE {
bool isVolatile() const {
if (IntrID != 0)
- return Info.IsVolatile;
+ return Info.getIsVolatile();
if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
return LI->isVolatile();
@@ -787,13 +787,13 @@ class EarlyCSE {
bool mayReadFromMemory() const {
if (IntrID != 0)
- return Info.ReadMem;
+ return Info.getReadMem();
return Inst->mayReadFromMemory();
}
bool mayWriteToMemory() const {
if (IntrID != 0)
- return Info.WriteMem;
+ return Info.getWriteMem();
return Inst->mayWriteToMemory();
}
diff --git a/llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp b/llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp
index a22a2e5e62f08..466aec5fdd1c6 100644
--- a/llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp
+++ b/llvm/lib/Transforms/Scalar/ExpandMemCmp.cpp
@@ -13,6 +13,7 @@
#include "llvm/Transforms/Scalar/ExpandMemCmp.h"
#include "ScalarOptions.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DomTreeUpdater.h"
@@ -81,7 +82,7 @@ class MemCmpExpansion {
std::vector<BasicBlock *> LoadCmpBlocks;
BasicBlock *EndBlock = nullptr;
PHINode *PhiRes = nullptr;
- const bool IsUsedForZeroCmp;
+ bool getIsUsedForZeroCmp() const { return LoadSequence.getFlag(0); }
const DataLayout &DL;
const TargetTransformInfo &TTI;
// The known common alignment of the two source pointers.
@@ -102,7 +103,7 @@ class MemCmpExpansion {
uint64_t Offset;
};
using LoadEntryVector = SmallVector<LoadEntry, 8>;
- LoadEntryVector LoadSequence;
+ llvm::SmallVectorWithFlagsFor<LoadEntryVector, 1> LoadSequence;
void createLoadCmpBlocks();
void createResultBlock();
@@ -137,9 +138,7 @@ class MemCmpExpansion {
unsigned MaxNumLoads) const;
void optimiseLoadSequence(
- LoadEntryVector &LoadSequence,
- const TargetTransformInfo::MemCmpExpansionOptions &Options,
- bool IsUsedForZeroCmp) const;
+ const TargetTransformInfo::MemCmpExpansionOptions &Options);
public:
MemCmpExpansion(CallInst *CI, uint64_t Size,
@@ -259,14 +258,12 @@ MemCmpExpansion::computeOverlappingLoadSequence(
}
void MemCmpExpansion::optimiseLoadSequence(
- LoadEntryVector &LoadSequence,
- const TargetTransformInfo::MemCmpExpansionOptions &Options,
- bool IsUsedForZeroCmp) const {
+ const TargetTransformInfo::MemCmpExpansionOptions &Options) {
// This part of code attempts to optimize the LoadSequence by merging allowed
// subsequences into single loads of allowed sizes from
// `MemCmpExpansionOptions::AllowedTailExpansions`. If it is for zero
// comparison or if no allowed tail expansions are specified, we exit early.
- if (IsUsedForZeroCmp || Options.AllowedTailExpansions.empty())
+ if (getIsUsedForZeroCmp() || Options.AllowedTailExpansions.empty())
return;
while (LoadSequence.size() >= 2) {
@@ -313,9 +310,10 @@ MemCmpExpansion::MemCmpExpansion(
DomTreeUpdater *DTU, const TargetTransformInfo &TTI, Align CommonAlign,
unsigned MaxBytesPerBlock)
: CI(CI), Size(Size), NumLoadsPerBlock(Options.NumLoadsPerBlock),
- MaxBytesPerBlock(MaxBytesPerBlock), IsUsedForZeroCmp(IsUsedForZeroCmp),
- DL(TheDataLayout), TTI(TTI), CommonAlign(CommonAlign), DTU(DTU),
- Builder(CI) {
+ MaxBytesPerBlock(MaxBytesPerBlock), DL(TheDataLayout), TTI(TTI),
+ CommonAlign(CommonAlign), DTU(DTU), Builder(CI),
+ LoadSequence(
+ decltype(this->LoadSequence)::withFlags(unsigned(IsUsedForZeroCmp))) {
assert(Size > 0 && "zero blocks");
assert(NumLoadsPerBlock > 0 && "zero loads per block");
// Scale the max size down if the target can load more bytes than we need.
@@ -326,8 +324,8 @@ MemCmpExpansion::MemCmpExpansion(
assert(!LoadSizes.empty() && "cannot load Size bytes");
MaxLoadSize = LoadSizes.front();
// Compute the decomposition.
- LoadSequence =
- computeGreedyLoadSequence(Size, LoadSizes, Options.MaxNumLoads);
+ LoadSequence.assign(
+ computeGreedyLoadSequence(Size, LoadSizes, Options.MaxNumLoads));
assert(LoadSequence.size() <= Options.MaxNumLoads && "broken invariant");
// If we allow overlapping loads and the load sequence is not already optimal,
// use overlapping loads.
@@ -338,11 +336,12 @@ MemCmpExpansion::MemCmpExpansion(
if (!OverlappingLoads.empty() &&
(LoadSequence.empty() ||
OverlappingLoads.size() < LoadSequence.size())) {
- LoadSequence = OverlappingLoads;
+ if (LoadSequence.data() != OverlappingLoads.data())
+ LoadSequence.assign(OverlappingLoads.begin(), OverlappingLoads.end());
}
}
assert(LoadSequence.size() <= Options.MaxNumLoads && "broken invariant");
- optimiseLoadSequence(LoadSequence, Options, IsUsedForZeroCmp);
+ optimiseLoadSequence(Options);
unsigned LoadIndex = 0;
while (LoadIndex < getNumLoads()) {
@@ -356,7 +355,7 @@ MemCmpExpansion::MemCmpExpansion(
}
unsigned MemCmpExpansion::getNumLoadsInBlock(unsigned LoadIndex) const {
- if (IsUsedForZeroCmp)
+ if (getIsUsedForZeroCmp())
return std::min<uint64_t>(getNumLoads() - LoadIndex, NumLoadsPerBlock);
unsigned NumLoads = 0;
@@ -662,7 +661,7 @@ void MemCmpExpansion::emitLoadCompareBlock(unsigned BlockIndex,
// Add the loaded values to the phi nodes for calculating memcmp result only
// if result is not used in a zero equality.
- if (!IsUsedForZeroCmp) {
+ if (!getIsUsedForZeroCmp()) {
ResBlock.PhiSrc1->addIncoming(Loads.Lhs, LoadCmpBlocks[BlockIndex]);
ResBlock.PhiSrc2->addIncoming(Loads.Rhs, LoadCmpBlocks[BlockIndex]);
}
@@ -696,7 +695,7 @@ void MemCmpExpansion::emitLoadCompareBlock(unsigned BlockIndex,
void MemCmpExpansion::emitMemCmpResultBlock() {
// Special case: if memcmp result is used in a zero equality, result does not
// need to be calculated and can simply return 1.
- if (IsUsedForZeroCmp) {
+ if (getIsUsedForZeroCmp()) {
BasicBlock::iterator InsertPt = ResBlock.BB->getFirstInsertionPt();
Builder.SetInsertPoint(InsertPt);
Value *Res = ConstantInt::get(Type::getInt32Ty(CI->getContext()), 1);
@@ -856,7 +855,8 @@ Value *MemCmpExpansion::getMemCmpExpansion() {
// calculate which source was larger. The calculation requires the
// two loaded source values of each load compare block.
// These will be saved in the phi nodes created by setupResultBlockPHINodes.
- if (!IsUsedForZeroCmp) setupResultBlockPHINodes();
+ if (!getIsUsedForZeroCmp())
+ setupResultBlockPHINodes();
// Create the number of required load compare basic blocks.
createLoadCmpBlocks();
@@ -871,7 +871,7 @@ Value *MemCmpExpansion::getMemCmpExpansion() {
Builder.SetCurrentDebugLocation(CI->getDebugLoc());
- if (IsUsedForZeroCmp)
+ if (getIsUsedForZeroCmp())
return getNumBlocks() == 1 ? getMemCmpEqZeroOneBlock()
: getMemCmpExpansionZeroCase();
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 113b3abf484cd..45d0c20a0a2fd 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -25,6 +25,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumeBundleQueries.h"
@@ -291,7 +292,8 @@ class llvm::GVNPassImpl {
// This is set 'true' initially and also when new blocks have been added to
// the function being analyzed. This boolean is used to control the updating
// of BlockRPONumber prior to accessing the contents of BlockRPONumber.
- bool InvalidBlockRPONumbers = true;
+ bool getInvalidBlockRPONumbers() const { return !ToSplit.getFlag(0); }
+ void setInvalidBlockRPONumbers(bool Value) { ToSplit.setFlag(0, !Value); }
using LoadDepVect = SmallVector<NonLocalDepResult, 64>;
using AvailValInBlkVect = SmallVector<AvailableValueInBlock, 64>;
@@ -303,7 +305,7 @@ class llvm::GVNPassImpl {
OptimizationRemarkEmitter *ORE, MemorySSA *MSSA = nullptr);
// List of critical edges to be split between iterations.
- SmallVector<std::pair<Instruction *, unsigned>, 4> ToSplit;
+ llvm::SmallVectorWithFlags<std::pair<Instruction *, unsigned>, 4> ToSplit;
enum class DepKind {
Other = 0, // Unknown value.
@@ -3422,7 +3424,7 @@ void GVNPassImpl::assignBlockRPONumber(Function &F) {
ReversePostOrderTraversal<Function *> RPOT(&F);
for (BasicBlock *BB : RPOT)
BlockRPONumber[BB] = NextBlockNumber++;
- InvalidBlockRPONumbers = false;
+ setInvalidBlockRPONumbers(false);
}
/// The given values are known to be equal in every use
@@ -3853,7 +3855,7 @@ bool GVNPassImpl::run(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
// IsMSSAEnabled is turned on.
VN.setMemorySSA(MSSA, isMemorySSAEnabled());
ORE = RunORE;
- InvalidBlockRPONumbers = true;
+ setInvalidBlockRPONumbers(true);
MemorySSAUpdater Updater(MSSA);
MSSAU = MSSA ? &Updater : nullptr;
@@ -4022,7 +4024,7 @@ bool GVNPassImpl::performScalarPRE(Instruction *CurInst) {
BasicBlock *CurrentBlock = CurInst->getParent();
// Update the RPO numbers for this function.
- if (InvalidBlockRPONumbers)
+ if (getInvalidBlockRPONumbers())
assignBlockRPONumber(*CurrentBlock->getParent());
SmallVector<std::pair<Value *, BasicBlock *>, 8> PredMap;
@@ -4177,7 +4179,7 @@ BasicBlock *GVNPassImpl::splitCriticalEdges(BasicBlock *Pred,
if (BB) {
if (MD)
MD->invalidateCachedPredecessors();
- InvalidBlockRPONumbers = true;
+ setInvalidBlockRPONumbers(true);
}
return BB;
}
@@ -4198,7 +4200,7 @@ bool GVNPassImpl::splitCriticalEdges() {
if (Changed) {
if (MD)
MD->invalidateCachedPredecessors();
- InvalidBlockRPONumbers = true;
+ setInvalidBlockRPONumbers(true);
}
return Changed;
}
@@ -4225,7 +4227,7 @@ void GVNPassImpl::cleanupGlobalSets() {
LeaderTable.clear();
BlockRPONumber.clear();
ICF->clear();
- InvalidBlockRPONumbers = true;
+ setInvalidBlockRPONumbers(true);
}
void GVNPassImpl::removeInstruction(Instruction *I) {
diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index 267eabedce27f..4e912c072e50a 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -28,8 +28,10 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -100,10 +102,12 @@ class IndVarSimplify {
const TargetTransformInfo *TTI;
std::unique_ptr<MemorySSAUpdater> MSSAU;
- SmallVector<WeakTrackingVH, 16> DeadInsts;
- bool WidenIndVars;
+ llvm::SmallVectorWithFlags<WeakTrackingVH, 16, 2> DeadInsts;
+ bool getWidenIndVars() const { return DeadInsts.getFlag(0); }
+ void setWidenIndVars(bool Value) { DeadInsts.setFlag(0, Value); }
- bool RunUnswitching = false;
+ bool getRunUnswitching() const { return DeadInsts.getFlag(1); }
+ void setRunUnswitching(bool Value) { DeadInsts.setFlag(1, Value); }
bool handleFloatingPointIV(Loop *L, PHINode *PH);
bool rewriteNonIntegerIVs(Loop *L);
@@ -127,20 +131,29 @@ class IndVarSimplify {
bool sinkUnusedInvariants(Loop *L);
+ template <typename CallbackT>
+ decltype(auto) withDeadInsts(CallbackT &&Callback) {
+ SmallVector<WeakTrackingVH, 16> Pending;
+ Pending = std::move(DeadInsts);
+ auto Restore = scope_exit([&] { DeadInsts.assign(std::move(Pending)); });
+ return Callback(Pending);
+ }
+
public:
IndVarSimplify(const ScalarOptions &Opts, LoopInfo *LI, ScalarEvolution *SE,
DominatorTree *DT, const DataLayout &DL,
TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
MemorySSA *MSSA, bool WidenIndVars)
: Opts(Opts), LI(LI), SE(SE), DT(DT), DL(DL), TLI(TLI), TTI(TTI),
- WidenIndVars(WidenIndVars) {
+ DeadInsts(
+ decltype(this->DeadInsts)::withFlags(unsigned(WidenIndVars))) {
if (MSSA)
MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
}
bool run(Loop *L);
- bool runUnswitching() const { return RunUnswitching; }
+ bool runUnswitching() const { return getRunUnswitching(); }
};
} // end anonymous namespace
@@ -695,26 +708,30 @@ bool IndVarSimplify::simplifyAndExtend(Loop *L,
// Information about sign/zero extensions of CurrIV.
IndVarSimplifyVisitor Visitor(CurrIV, SE, TTI, DT);
- const auto &[C, U] = simplifyUsersOfIV(CurrIV, SE, DT, LI, TTI, DeadInsts,
- Rewriter, &Visitor);
+ const auto &[C, U] = withDeadInsts([&](auto &DeadInsts) {
+ return simplifyUsersOfIV(CurrIV, SE, DT, LI, TTI, DeadInsts, Rewriter,
+ &Visitor);
+ });
Changed |= C;
- RunUnswitching |= U;
+ setRunUnswitching(int(getRunUnswitching()) | (U));
if (Visitor.WI.WidestNativeType) {
WideIVs.push_back(Visitor.WI);
}
} while(!LoopPhis.empty());
// Continue if we disallowed widening.
- if (!WidenIndVars)
+ if (!getWidenIndVars())
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, Opts.indvars_post_increment_ranges)) {
+ if (PHINode *WidePhi = withDeadInsts([&](auto &DeadInsts) {
+ return createWideIV(WideIVs.back(), LI, SE, Rewriter, DT, DeadInsts,
+ ElimExt, Widened, HasGuards,
+ Opts.indvars_post_increment_ranges);
+ })) {
NumElimExt += ElimExt;
NumWidened += Widened;
Changed = true;
@@ -1646,7 +1663,9 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
// unconditional exit, we can still replace header phis with their
// preheader value.
if (!L->contains(BI->getSuccessor(CI->isNullValue())))
- replaceLoopPHINodesWithPreheaderValues(LI, L, DeadInsts, *SE);
+ withDeadInsts([&](auto &DeadInsts) {
+ return replaceLoopPHINodesWithPreheaderValues(LI, L, DeadInsts, *SE);
+ });
return true;
}
@@ -1707,9 +1726,11 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
// will remain the same within iteration space?
auto *BI = cast<CondBrInst>(ExitingBB->getTerminator());
auto OptimizeCond = [&](bool SkipLastIter) {
- return optimizeLoopExitWithUnknownExitCount(L, BI, ExitingBB,
- MaxBECount, SkipLastIter,
- SE, Rewriter, DeadInsts);
+ return withDeadInsts([&](auto &DeadInsts) {
+ return optimizeLoopExitWithUnknownExitCount(L, BI, ExitingBB,
+ MaxBECount, SkipLastIter,
+ SE, Rewriter, DeadInsts);
+ });
};
// TODO: We might have proved that we can skip the last iteration for
@@ -1744,8 +1765,12 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
// We know that the backedge can't be taken, so we replace all
// the header PHIs with values coming from the preheader.
if (ExactExitCount->isZero()) {
- foldExit(L, ExitingBB, true, DeadInsts);
- replaceLoopPHINodesWithPreheaderValues(LI, L, DeadInsts, *SE);
+ withDeadInsts([&](auto &DeadInsts) {
+ return foldExit(L, ExitingBB, true, DeadInsts);
+ });
+ withDeadInsts([&](auto &DeadInsts) {
+ return replaceLoopPHINodesWithPreheaderValues(LI, L, DeadInsts, *SE);
+ });
Changed = true;
continue;
}
@@ -1764,7 +1789,9 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
// one?
if (SE->isLoopEntryGuardedByCond(L, CmpInst::ICMP_ULT, MaxBECount,
ExactExitCount)) {
- foldExit(L, ExitingBB, false, DeadInsts);
+ withDeadInsts([&](auto &DeadInsts) {
+ return foldExit(L, ExitingBB, false, DeadInsts);
+ });
Changed = true;
continue;
}
@@ -1774,7 +1801,9 @@ 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 (!DominatingExactExitCounts.insert(ExactExitCount).second) {
- foldExit(L, ExitingBB, false, DeadInsts);
+ withDeadInsts([&](auto &DeadInsts) {
+ return foldExit(L, ExitingBB, false, DeadInsts);
+ });
Changed = true;
continue;
}
@@ -2005,7 +2034,7 @@ bool IndVarSimplify::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
if (OldCond->use_empty())
DeadInsts.emplace_back(OldCond);
Changed = true;
- RunUnswitching = true;
+ setRunUnswitching(true);
}
return Changed;
@@ -2057,15 +2086,19 @@ bool IndVarSimplify::run(Loop *L) {
// loop into any instructions outside of the loop that use the final values
// of the current expressions.
if (Opts.replexitval != NeverRepl) {
- if (int Rewrites = rewriteLoopExitValues(L, LI, TLI, SE, TTI, Rewriter, DT,
- Opts.replexitval, DeadInsts)) {
+ if (int Rewrites = withDeadInsts([&](auto &DeadInsts) {
+ return rewriteLoopExitValues(L, LI, TLI, SE, TTI, Rewriter, DT,
+ Opts.replexitval, DeadInsts);
+ })) {
NumReplaced += Rewrites;
Changed = true;
}
}
// Eliminate redundant IV cycles.
- NumElimIV += Rewriter.replaceCongruentIVs(L, DT, DeadInsts, TTI);
+ NumElimIV += withDeadInsts([&](auto &DeadInsts) {
+ return Rewriter.replaceCongruentIVs(L, DT, DeadInsts, TTI);
+ });
// Try to convert exit conditions to unsigned and rotate computation
// out of the loop. Note: Handles invalidation internally if needed.
diff --git a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
index 0044174efcb66..dd80039aaa848 100644
--- a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
@@ -29,6 +29,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -96,12 +97,14 @@ class InstPartition {
public:
InstPartition(Instruction *I, Loop *L, bool DepCycle = false)
- : DepCycle(DepCycle), OrigLoop(L) {
+ : OrigLoop(L),
+ ClonedLoopBlocks(
+ decltype(this->ClonedLoopBlocks)::withFlags(unsigned(DepCycle))) {
Set.insert(I);
}
/// Returns whether this partition contains a dependence cycle.
- bool hasDepCycle() const { return DepCycle; }
+ bool hasDepCycle() const { return getDepCycle(); }
/// Adds an instruction to this partition.
void add(Instruction *I) { Set.insert(I); }
@@ -118,7 +121,7 @@ class InstPartition {
void moveTo(InstPartition &Other) {
Other.Set.insert_range(Set);
Set.clear();
- Other.DepCycle |= DepCycle;
+ Other.setDepCycle(int(Other.getDepCycle()) | (getDepCycle()));
}
/// Populates the partition with a transitive closure of all the
@@ -151,9 +154,12 @@ class InstPartition {
Loop *cloneLoopWithPreheader(BasicBlock *InsertBefore, BasicBlock *LoopDomBB,
unsigned Index, LoopInfo *LI,
DominatorTree *DT) {
+ SmallVector<BasicBlock *, 8> Blocks;
+ Blocks = std::move(ClonedLoopBlocks);
ClonedLoop = ::cloneLoopWithPreheader(InsertBefore, LoopDomBB, OrigLoop,
VMap, Twine(".ldist") + Twine(Index),
- LI, DT, ClonedLoopBlocks);
+ LI, DT, Blocks);
+ ClonedLoopBlocks.assign(std::move(Blocks));
return ClonedLoop;
}
@@ -205,7 +211,7 @@ class InstPartition {
}
void print(raw_ostream &OS) const {
- OS << (DepCycle ? " (cycle)\n" : "\n");
+ OS << (getDepCycle() ? " (cycle)\n" : "\n");
for (auto *I : Set)
// Prefix with the block name.
OS << " " << I->getParent()->getName() << ":" << *I << "\n";
@@ -221,7 +227,8 @@ class InstPartition {
InstructionSet Set;
/// Whether this partition contains a dependence cycle.
- bool DepCycle;
+ bool getDepCycle() const { return ClonedLoopBlocks.getFlag(0); }
+ void setDepCycle(bool Value) { ClonedLoopBlocks.setFlag(0, Value); }
/// The original loop.
Loop *OrigLoop;
@@ -232,7 +239,7 @@ class InstPartition {
/// The blocks of ClonedLoop including the preheader. If this
/// partition is mapped to the original loop, this is empty.
- SmallVector<BasicBlock *, 8> ClonedLoopBlocks;
+ llvm::SmallVectorWithFlags<BasicBlock *, 8> ClonedLoopBlocks;
/// These gets populated once the set of instructions have been
/// finalized. If this partition is mapped to the original loop, these are not
@@ -596,9 +603,8 @@ class MemoryInstructionDependences {
AccessesType::const_iterator begin() const { return Accesses.begin(); }
AccessesType::const_iterator end() const { return Accesses.end(); }
- MemoryInstructionDependences(
- const SmallVectorImpl<Instruction *> &Instructions,
- const SmallVectorImpl<Dependence> &Dependences) {
+ MemoryInstructionDependences(ArrayRef<Instruction *> Instructions,
+ const SmallVectorImpl<Dependence> &Dependences) {
Accesses.append(Instructions.begin(), Instructions.end());
LLVM_DEBUG(dbgs() << "LDist: Backward dependences:\n");
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index b9e65fb0ed520..f091d2fa6e594 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -48,6 +48,7 @@
#include "ScalarOptions.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
@@ -139,17 +140,20 @@ struct FusionCandidate {
/// Vector of instructions in this loop that read from memory
SmallVector<Instruction *, 16> MemReads;
/// Vector of instructions in this loop that write to memory
- SmallVector<Instruction *, 16> MemWrites;
+ llvm::SmallVectorWithFlags<Instruction *, 16, 3> MemWrites;
/// Are all of the members of this fusion candidate still valid
- bool Valid;
+ bool getValid() const { return MemWrites.getFlag(0); }
+ void setValid(bool Value) { MemWrites.setFlag(0, Value); }
/// Guard branch of the loop, if it exists
CondBrInst *GuardBranch;
/// Peeling Paramaters of the Loop.
TTI::PeelingPreferences PP;
/// Can you Peel this Loop?
- bool AbleToPeel;
+ bool getAbleToPeel() const { return MemWrites.getFlag(1); }
+ void setAbleToPeel(bool Value) { MemWrites.setFlag(1, Value); }
/// Has this loop been Peeled
- bool Peeled;
+ bool getPeeled() const { return MemWrites.getFlag(2); }
+ void setPeeled(bool Value) { MemWrites.setFlag(2, Value); }
DominatorTree &DT;
const PostDominatorTree *PDT;
@@ -160,9 +164,11 @@ struct FusionCandidate {
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) {
+ Latch(L->getLoopLatch()), L(L),
+ MemWrites(decltype(this->MemWrites)::withFlags(
+ (unsigned(bool(canPeel(L))) << 1) | 1)),
+ GuardBranch(L->getLoopGuardBranch()), PP(PP), 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
@@ -213,7 +219,7 @@ struct FusionCandidate {
/// Check if all members of the class are valid.
bool isValid() const {
return Preheader && ExitingBlock && ExitBlock && Latch && L &&
- !L->isInvalid() && Valid;
+ !L->isInvalid() && getValid();
}
/// Verify that all members are in sync with the Loop object.
@@ -259,7 +265,7 @@ struct FusionCandidate {
/// This method is only valid for guarded loops.
BasicBlock *getNonLoopBlock() const {
assert(GuardBranch && "Only valid on guarded loops.");
- if (Peeled)
+ if (getPeeled())
return GuardBranch->getSuccessor(1);
return (GuardBranch->getSuccessor(0) == Preheader)
? GuardBranch->getSuccessor(1)
@@ -336,7 +342,7 @@ struct FusionCandidate {
void invalidate() {
MemWrites.clear();
MemReads.clear();
- Valid = false;
+ setValid(false);
}
// Emit an analysis remark explaining why this loop cannot be fused. The
@@ -740,7 +746,7 @@ struct LoopFuser {
void peelFusionCandidate(FusionCandidate &FC0, const FusionCandidate &FC1,
unsigned PeelCount) {
- assert(FC0.AbleToPeel && "Should be able to peel loop");
+ assert(FC0.getAbleToPeel() && "Should be able to peel loop");
LLVM_DEBUG(dbgs() << "Attempting to peel first " << PeelCount
<< " iterations of the first loop. \n");
@@ -751,7 +757,7 @@ struct LoopFuser {
// simplifyLoop call.
peelLoop(FC0.L, PeelCount, /*PeelLast=*/false, &LI, &SE, DT, &AC,
/*PreserveLCSSA=*/false, VMap);
- FC0.Peeled = true;
+ FC0.setPeeled(true);
LLVM_DEBUG(dbgs() << "Done Peeling\n");
#ifndef NDEBUG
@@ -845,9 +851,10 @@ struct LoopFuser {
// the first loop has a larger trip count. In this case it is possible
// that the first loop is peeled to expose the fusion opportunity.
// Peeling the second loop is not currently supported.
- bool WillPeel = FC0.AbleToPeel && TCDifference && *TCDifference > 0 &&
- *TCDifference <= static_cast<int64_t>(
- Opts.loop_fusion_peel_max_count);
+ bool WillPeel =
+ FC0.getAbleToPeel() && TCDifference && *TCDifference > 0 &&
+ *TCDifference <=
+ static_cast<int64_t>(Opts.loop_fusion_peel_max_count);
if (!WillPeel && (!TCDifference || *TCDifference != 0)) {
LLVM_DEBUG(dbgs() << "Fusion candidates do not have identical trip "
@@ -1718,8 +1725,9 @@ struct LoopFuser {
if (FC0.GuardBranch)
return fuseGuardedLoops(FC0, FC1);
- assert(FC1.Preheader ==
- (FC0.Peeled ? FC0.ExitBlock->getUniqueSuccessor() : FC0.ExitBlock));
+ assert(FC1.Preheader == (FC0.getPeeled()
+ ? FC0.ExitBlock->getUniqueSuccessor()
+ : FC0.ExitBlock));
assert(FC1.Preheader->size() == 1 &&
FC1.Preheader->getSingleSuccessor() == FC1.Header);
@@ -1761,7 +1769,7 @@ struct LoopFuser {
// 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) {
+ if (!FC0.getPeeled()) {
FC0.ExitingBlock->getTerminator()->replaceUsesOfWith(FC1.Preheader,
FC1.Header);
TreeUpdates.emplace_back(DominatorTree::UpdateType(
@@ -1797,7 +1805,7 @@ struct LoopFuser {
LI.removeBlock(FC1.Preheader);
DTU.deleteBB(FC1.Preheader);
- if (FC0.Peeled) {
+ if (FC0.getPeeled()) {
LI.removeBlock(FC0.ExitBlock);
DTU.deleteBB(FC0.ExitBlock);
}
@@ -1881,8 +1889,8 @@ struct LoopFuser {
// 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, SE);
+ (FC0.getPeeled() ? *FC0ExitBlockSuccessor : *FC0.ExitBlock),
+ *FC1.ExitBlock, DT, PDT, DI, SE);
// Move instructions from the guard block of FC1 to the end of the guard
// block of FC0.
@@ -1903,7 +1911,8 @@ struct LoopFuser {
FC1NonLoopBlock->replacePhiUsesWith(FC1GuardBlock, FC0GuardBlock);
FC0.GuardBranch->replaceUsesOfWith(FC0NonLoopBlock, FC1NonLoopBlock);
- BasicBlock *BBToUpdate = FC0.Peeled ? FC0ExitBlockSuccessor : FC0.ExitBlock;
+ BasicBlock *BBToUpdate =
+ FC0.getPeeled() ? FC0ExitBlockSuccessor : FC0.ExitBlock;
BBToUpdate->getTerminator()->replaceUsesOfWith(FC1GuardBlock, FC1.Header);
// The guard of FC1 is not necessary anymore.
@@ -1919,7 +1928,7 @@ struct LoopFuser {
TreeUpdates.emplace_back(DominatorTree::UpdateType(
DominatorTree::Insert, FC0GuardBlock, FC1NonLoopBlock));
- if (FC0.Peeled) {
+ if (FC0.getPeeled()) {
TreeUpdates.emplace_back(DominatorTree::UpdateType(
DominatorTree::Delete, FC0.ExitBlock, FC0ExitBlockSuccessor));
// Remove the Block after the ExitBlock of FC0
@@ -2012,7 +2021,7 @@ struct LoopFuser {
LI.removeBlock(FC1GuardBlock);
LI.removeBlock(FC1.Preheader);
LI.removeBlock(FC0.ExitBlock);
- if (FC0.Peeled) {
+ if (FC0.getPeeled()) {
LI.removeBlock(FC0ExitBlockSuccessor);
DTU.deleteBB(FC0ExitBlockSuccessor);
}
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index a188c33528e5e..370a9a2f9a6a4 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -37,6 +37,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -172,7 +173,12 @@ class LoopIdiomRecognize {
const TargetTransformInfo *TTI;
const DataLayout *DL;
OptimizationRemarkEmitter &ORE;
- bool ApplyCodeSizeHeuristics;
+ bool getApplyCodeSizeHeuristics() const {
+ return StoreRefsForMemcpy.getFlag(0);
+ }
+ void setApplyCodeSizeHeuristics(bool Value) {
+ StoreRefsForMemcpy.setFlag(0, Value);
+ }
std::unique_ptr<MemorySSAUpdater> MSSAU;
public:
@@ -196,10 +202,13 @@ class LoopIdiomRecognize {
StoreListMap StoreRefsForMemset;
StoreListMap StoreRefsForMemsetPattern;
- StoreList StoreRefsForMemcpy;
- bool HasMemset;
- bool HasMemsetPattern;
- bool HasMemcpy;
+ llvm::SmallVectorWithFlagsFor<StoreList, 4> StoreRefsForMemcpy;
+ bool getHasMemset() const { return StoreRefsForMemcpy.getFlag(1); }
+ void setHasMemset(bool Value) { StoreRefsForMemcpy.setFlag(1, Value); }
+ bool getHasMemsetPattern() const { return StoreRefsForMemcpy.getFlag(2); }
+ void setHasMemsetPattern(bool Value) { StoreRefsForMemcpy.setFlag(2, Value); }
+ bool getHasMemcpy() const { return StoreRefsForMemcpy.getFlag(3); }
+ void setHasMemcpy(bool Value) { StoreRefsForMemcpy.setFlag(3, Value); }
/// Return code for isLegalStore()
enum LegalStoreKind {
@@ -333,20 +342,20 @@ bool LoopIdiomRecognize::runOnLoop(Loop *L) {
return false;
// Determine if code size heuristics need to be applied.
- ApplyCodeSizeHeuristics =
- L->getHeader()->getParent()->hasOptSize() && Opts.use_lir_code_size_heurs;
+ setApplyCodeSizeHeuristics(L->getHeader()->getParent()->hasOptSize() &&
+ Opts.use_lir_code_size_heurs);
- HasMemset = TLI->has(LibFunc_memset);
+ setHasMemset(TLI->has(LibFunc_memset));
// TODO: Unconditionally enable use of the memset pattern intrinsic (or at
// least, opt-in via target hook) once we are confident it will never result
// in worse codegen than without. For now, use it only when the target
// supports memset_pattern16 libcall (or unless this is overridden by
// command line option).
- HasMemsetPattern = TLI->has(LibFunc_memset_pattern16);
- HasMemcpy = TLI->has(LibFunc_memcpy);
+ setHasMemsetPattern(TLI->has(LibFunc_memset_pattern16));
+ setHasMemcpy(TLI->has(LibFunc_memcpy));
- if (HasMemset || HasMemsetPattern ||
- Opts.loop_idiom_force_memset_pattern_intrinsic || HasMemcpy ||
+ if (getHasMemset() || getHasMemsetPattern() ||
+ Opts.loop_idiom_force_memset_pattern_intrinsic || getHasMemcpy() ||
!DisableLIRP::HashRecognize)
if (SE->hasLoopInvariantBackedgeTakenCount(L))
return runOnCountableLoop();
@@ -507,7 +516,7 @@ LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
// If we're allowed to form a memset, and the stored value would be
// acceptable for memset, use it.
- if (!MustPreserveExternalState && !UnorderedAtomic && HasMemset &&
+ if (!MustPreserveExternalState && !UnorderedAtomic && getHasMemset() &&
SplatValue && !DisableLIRP::Memset &&
// Verify that the stored value is loop invariant. If not, we can't
// promote the memset.
@@ -516,7 +525,8 @@ LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
return LegalStoreKind::Memset;
}
if (!MustPreserveExternalState && !UnorderedAtomic &&
- (HasMemsetPattern || Opts.loop_idiom_force_memset_pattern_intrinsic) &&
+ (getHasMemsetPattern() ||
+ Opts.loop_idiom_force_memset_pattern_intrinsic) &&
!DisableLIRP::Memset &&
// Don't create memset_pattern16s with address spaces.
StorePtr->getType()->getPointerAddressSpace() == 0 &&
@@ -526,7 +536,7 @@ LoopIdiomRecognize::isLegalStore(StoreInst *SI) {
}
// Otherwise, see if the store can be turned into a memcpy.
- if (HasMemcpy && !DisableLIRP::Memcpy) {
+ if (getHasMemcpy() && !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.
unsigned StoreSize = DL->getTypeStoreSize(SI->getValueOperand()->getType());
@@ -815,7 +825,7 @@ bool LoopIdiomRecognize::processLoopMemCpy(MemCpyInst *MCI,
// If we're not allowed to hack on memcpy, we fail. We don't mess with the
// inlined version as generating a larger inline mempcy could affect code
// size.
- if (!HasMemcpy || MCI->isForceInlined() || DisableLIRP::Memcpy)
+ if (!getHasMemcpy() || MCI->isForceInlined() || DisableLIRP::Memcpy)
return false;
Value *Dest = MCI->getDest();
@@ -879,7 +889,7 @@ bool LoopIdiomRecognize::processLoopMemSet(MemSetInst *MSI,
// If we're not allowed to hack on memset, we fail. We don't mess with the
// inlined version as generating a larger memset could affect code size.
- if (!HasMemset || MSI->isForceInlined() || DisableLIRP::Memset)
+ if (!getHasMemset() || MSI->isForceInlined() || DisableLIRP::Memset)
return false;
Value *Pointer = MSI->getDest();
@@ -1141,8 +1151,8 @@ bool LoopIdiomRecognize::processLoopStridedStore(
Value *MemsetArg;
std::optional<int64_t> BytesWritten;
- if (PatternValue &&
- (HasMemsetPattern || Opts.loop_idiom_force_memset_pattern_intrinsic)) {
+ if (PatternValue && (getHasMemsetPattern() ||
+ Opts.loop_idiom_force_memset_pattern_intrinsic)) {
const SCEV *TripCountS =
SE->getTripCountFromExitCount(BECount, IntIdxTy, CurLoop);
if (!Expander.isSafeToExpand(TripCountS))
@@ -1567,7 +1577,7 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
//
bool LoopIdiomRecognize::avoidLIRForMultiBlockLoop(bool IsMemset,
bool IsLoopMemset) {
- if (ApplyCodeSizeHeuristics && CurLoop->getNumBlocks() > 1) {
+ if (getApplyCodeSizeHeuristics() && CurLoop->getNumBlocks() > 1) {
if (CurLoop->isOutermost() && (!IsMemset || !IsLoopMemset)) {
LLVM_DEBUG(dbgs() << " " << CurLoop->getHeader()->getParent()->getName()
<< " : LIR " << (IsMemset ? "Memset" : "Memcpy")
@@ -1683,7 +1693,7 @@ bool LoopIdiomRecognize::optimizeCRCLoop(const PolynomialInfo &Info) {
// TODO: The clmul optimization is around the same size in many cases, so it
// could be worth it to take advantage of that fact, especially if it would
// be much faster than the original loop.
- if (ApplyCodeSizeHeuristics) {
+ if (getApplyCodeSizeHeuristics()) {
ReportMissed("optimizing for size");
return false;
}
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
index a2ff998864456..8a1f57bf67440 100644
--- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
@@ -16,6 +16,7 @@
#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
#include "ScalarOptions.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -113,7 +114,8 @@ class ConstantTerminatorFoldingImpl {
SmallVector<DominatorTree::UpdateType, 16> DTUpdates;
// Whether or not the current loop has irreducible CFG.
- bool HasIrreducibleCFG = false;
+ bool getHasIrreducibleCFG() const { return FoldCandidates.getFlag(0); }
+ void setHasIrreducibleCFG(bool Value) { FoldCandidates.setFlag(0, Value); }
// Whether or not the current loop will still exist after terminator constant
// folding will be done. In theory, there are two ways how it can happen:
// 1. Loop's latch(es) become unreachable from loop header;
@@ -122,9 +124,11 @@ class ConstantTerminatorFoldingImpl {
// current loop and its preheader and do not affect preheader's reachibility
// from any other block. So this variable set to true means that loop's latch
// has become unreachable from loop header.
- bool DeleteCurrentLoop = false;
+ bool getDeleteCurrentLoop() const { return FoldCandidates.getFlag(1); }
+ void setDeleteCurrentLoop(bool Value) { FoldCandidates.setFlag(1, Value); }
// Whether or not we enter the loop through an indirectbr.
- bool HasIndirectEntry = false;
+ bool getHasIndirectEntry() const { return FoldCandidates.getFlag(2); }
+ void setHasIndirectEntry(bool Value) { FoldCandidates.setFlag(2, Value); }
// The blocks of the original loop that will still be reachable from entry
// after the constant folding.
@@ -143,16 +147,15 @@ class ConstantTerminatorFoldingImpl {
// The blocks that have terminators with constant condition that can be
// folded. Note: fold candidates should be in L but not in any of its
// subloops to avoid complex LI updates.
- SmallVector<BasicBlock *, 8> FoldCandidates;
+ llvm::SmallVectorWithFlags<BasicBlock *, 8, 3> FoldCandidates;
void dump() const {
dbgs() << "Constant terminator folding for loop " << L << "\n";
dbgs() << "After terminator constant-folding, the loop will";
- if (!DeleteCurrentLoop)
+ if (!getDeleteCurrentLoop())
dbgs() << " not";
dbgs() << " be destroyed\n";
- auto PrintOutVector = [&](const char *Message,
- const SmallVectorImpl<BasicBlock *> &S) {
+ auto PrintOutVector = [&](const char *Message, ArrayRef<BasicBlock *> S) {
dbgs() << Message << "\n";
for (const BasicBlock *BB : S)
dbgs() << "\t" << BB->getName() << "\n";
@@ -169,7 +172,7 @@ class ConstantTerminatorFoldingImpl {
PrintOutVector("Dead blocks from the original loop:", DeadLoopBlocks);
PrintOutSet("Live exit blocks:", LiveExitBlocks);
PrintOutVector("Dead exit blocks:", DeadExitBlocks);
- if (!DeleteCurrentLoop)
+ if (!getDeleteCurrentLoop())
PrintOutSet("The following blocks will still be part of the loop:",
BlocksInLoopAfterFolding);
}
@@ -209,7 +212,7 @@ class ConstantTerminatorFoldingImpl {
// on this). We can later decide to support such cases by altering the
// algorithms, but so far we just give up analyzing them.
if (hasIrreducibleCFG(DFS)) {
- HasIrreducibleCFG = true;
+ setHasIrreducibleCFG(true);
return;
}
@@ -222,7 +225,7 @@ class ConstantTerminatorFoldingImpl {
return isa<IndirectBrInst>(Pred->getTerminator());
}) &&
"Loop should have preheader if it is not entered indirectly");
- HasIndirectEntry = true;
+ setHasIndirectEntry(true);
return;
}
@@ -285,11 +288,11 @@ class ConstantTerminatorFoldingImpl {
};
// The loop will not be destroyed if its latch is live.
- DeleteCurrentLoop = !IsEdgeLive(L.getLoopLatch(), L.getHeader());
+ setDeleteCurrentLoop(!IsEdgeLive(L.getLoopLatch(), L.getHeader()));
// If we are going to delete the current loop completely, no extra analysis
// is needed.
- if (DeleteCurrentLoop)
+ if (getDeleteCurrentLoop())
return;
// Otherwise, we should check which blocks will still be a part of the
@@ -561,12 +564,12 @@ class ConstantTerminatorFoldingImpl {
LLVM_DEBUG(dbgs() << "In function " << Header->getParent()->getName()
<< ": ");
- if (HasIrreducibleCFG) {
+ if (getHasIrreducibleCFG()) {
LLVM_DEBUG(dbgs() << "Loops with irreducible CFG are not supported!\n");
return false;
}
- if (HasIndirectEntry) {
+ if (getHasIndirectEntry()) {
LLVM_DEBUG(dbgs() << "Loops which can be entered indirectly are not"
" supported!\n");
return false;
@@ -581,7 +584,7 @@ class ConstantTerminatorFoldingImpl {
}
// TODO: Support deletion of the current loop.
- if (DeleteCurrentLoop) {
+ if (getDeleteCurrentLoop()) {
LLVM_DEBUG(
dbgs()
<< "Give up constant terminator folding in loop " << Header->getName()
@@ -656,9 +659,7 @@ class ConstantTerminatorFoldingImpl {
return true;
}
- bool foldingBreaksCurrentLoop() const {
- return DeleteCurrentLoop;
- }
+ bool foldingBreaksCurrentLoop() const { return getDeleteCurrentLoop(); }
};
} // namespace
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 6073a177babaf..5b176b0c9d169 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -64,6 +64,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AssumptionCache.h"
@@ -424,7 +425,8 @@ struct Formula {
Immediate BaseOffset = Immediate::getZero();
/// Whether any complex addressing has a base register.
- bool HasBaseReg = false;
+ bool getHasBaseReg() const { return BaseRegs.getFlag(0); }
+ void setHasBaseReg(bool Value) { BaseRegs.setFlag(0, Value); }
/// The scale of any complex addressing.
int64_t Scale = 0;
@@ -443,7 +445,7 @@ struct Formula {
/// This invariant can be temporarily broken while building a formula.
/// However, every formula inserted into the LSRInstance must be in canonical
/// form.
- SmallVector<const SCEV *, 4> BaseRegs;
+ llvm::SmallVectorWithFlags<const SCEV *, 4> BaseRegs;
/// The 'scaled' register for this use. This should be non-null when Scale is
/// not zero.
@@ -547,13 +549,13 @@ void Formula::initialMatch(const SCEV *S, Loop *L, ScalarEvolution &SE) {
const SCEV *Sum = SE.getAddExpr(Good);
if (!Sum->isZero())
BaseRegs.push_back(Sum);
- HasBaseReg = true;
+ setHasBaseReg(true);
}
if (!Bad.empty()) {
const SCEV *Sum = SE.getAddExpr(Bad);
if (!Sum->isZero())
BaseRegs.push_back(Sum);
- HasBaseReg = true;
+ setHasBaseReg(true);
}
canonicalize(*L);
}
@@ -714,9 +716,9 @@ void Formula::print(raw_ostream &OS) const {
for (const SCEV *BaseReg : BaseRegs)
OS << Plus << "reg(" << *BaseReg << ')';
- if (HasBaseReg && BaseRegs.empty())
+ if (getHasBaseReg() && BaseRegs.empty())
OS << Plus << "**error: HasBaseReg**";
- else if (!HasBaseReg && !BaseRegs.empty())
+ else if (!getHasBaseReg() && !BaseRegs.empty())
OS << Plus << "**error: !HasBaseReg**";
if (Scale != 0) {
@@ -1299,24 +1301,30 @@ class LSRUse {
/// This records whether all of the fixups using this LSRUse are outside of
/// the loop, in which case some special-case heuristics may be used.
- bool AllFixupsOutsideLoop = true;
+ bool getAllFixupsOutsideLoop() const { return !Formulae.getFlag(0); }
+ void setAllFixupsOutsideLoop(bool Value) { Formulae.setFlag(0, !Value); }
/// This records whether all of the fixups using this LSRUse are unconditional
/// within the loop, meaning they will be executed on every path to the loop
/// latch. This includes fixups before early exits.
- bool AllFixupsUnconditional = true;
+ bool getAllFixupsUnconditional() const { return !Formulae.getFlag(1); }
+ void setAllFixupsUnconditional(bool Value) { Formulae.setFlag(1, !Value); }
/// RigidFormula is set to true to guarantee that this use will be associated
/// with a single formula--the one that initially matched. Some SCEV
/// expressions cannot be expanded. This allows LSR to consider the registers
/// used by those expressions without the need to expand them later after
/// changing the formula.
- bool RigidFormula = false;
+ bool getRigidFormula() const { return Formulae.getFlag(2); }
+ bool setRigidFormula(bool Value) {
+ Formulae.setFlag(2, Value);
+ return Value;
+ }
/// A list of ways to build a value that can satisfy this user. After the
/// list is populated, one of these is selected heuristically and used to
/// formulate a replacement for OperandValToReplace in UserInst.
- SmallVector<Formula, 12> Formulae;
+ llvm::SmallVectorWithFlags<Formula, 12, 3> Formulae;
/// The set of register candidates used by all formulae in this LSRUse.
SmallPtrSet<const SCEV *, 4> Regs;
@@ -1422,7 +1430,7 @@ void Cost::RateRegister(const Formula &F, const SCEV *Reg,
!isa<SCEVConstant>(Start) &&
SE->isLoopInvariant(Start, L);
// We can only pre or post index when the load/store is unconditional.
- if ((CanPreIndex || CanPostIndex) && LU.AllFixupsUnconditional)
+ if ((CanPreIndex || CanPostIndex) && LU.getAllFixupsUnconditional())
LoopCost = 0;
}
}
@@ -1543,7 +1551,8 @@ void Cost::RateFormula(const Formula &F, SmallPtrSetImpl<const SCEV *> &Regs,
// specifically not supported.
if (LU.Kind == LSRUse::Address && Offset.isNonZero() &&
!isAMCompletelyFolded(*TTI, LSRUse::Address, LU.AccessTy, F.BaseGV,
- Offset, F.HasBaseReg, F.Scale, Fixup.UserInst))
+ Offset, F.getHasBaseReg(), F.Scale,
+ Fixup.UserInst))
C.NumBaseAdds++;
} else {
// Incompatible immediate type, increase cost to avoid using
@@ -1684,7 +1693,7 @@ LLVM_DUMP_METHOD void LSRFixup::dump() const {
/// Test whether this use as a formula which has the same registers as the given
/// formula.
bool LSRUse::HasFormulaWithSameRegs(const Formula &F) const {
- SmallVector<const SCEV *, 4> Key = F.BaseRegs;
+ SmallVector<const SCEV *, 4> Key(F.BaseRegs.begin(), F.BaseRegs.end());
if (F.ScaledReg) Key.push_back(F.ScaledReg);
// Unstable sort by host order ok, because this is only used for uniquifying.
llvm::sort(Key);
@@ -1705,10 +1714,10 @@ float LSRUse::getNotSelectedProbability(const SCEV *Reg) const {
bool LSRUse::InsertFormula(const Formula &F, const Loop &L) {
assert(F.isCanonical(L) && "Invalid canonical representation");
- if (!Formulae.empty() && RigidFormula)
+ if (!Formulae.empty() && getRigidFormula())
return false;
- SmallVector<const SCEV *, 4> Key = F.BaseRegs;
+ SmallVector<const SCEV *, 4> Key(F.BaseRegs.begin(), F.BaseRegs.end());
if (F.ScaledReg) Key.push_back(F.ScaledReg);
// Unstable sort by host order ok, because this is only used for uniquifying.
llvm::sort(Key);
@@ -1785,10 +1794,10 @@ void LSRUse::print(raw_ostream &OS) const {
}
OS << '}';
- if (AllFixupsOutsideLoop)
+ if (getAllFixupsOutsideLoop())
OS << ", all-fixups-outside-loop";
- if (AllFixupsUnconditional)
+ if (getAllFixupsUnconditional())
OS << ", all-fixups-unconditional";
}
@@ -1900,7 +1909,8 @@ static bool isAMCompletelyFolded(const TargetTransformInfo &TTI,
// compile time sake.
assert((F.isCanonical(L) || F.Scale != 0));
return isAMCompletelyFolded(TTI, MinOffset, MaxOffset, Kind, AccessTy,
- F.BaseGV, F.BaseOffset, F.HasBaseReg, F.Scale);
+ F.BaseGV, F.BaseOffset, F.getHasBaseReg(),
+ F.Scale);
}
/// Test whether we know how to expand the current formula.
@@ -1922,7 +1932,7 @@ static bool isLegalUse(const TargetTransformInfo &TTI, Immediate MinOffset,
Immediate MaxOffset, LSRUse::KindType Kind,
MemAccessTy AccessTy, const Formula &F) {
return isLegalUse(TTI, MinOffset, MaxOffset, Kind, AccessTy, F.BaseGV,
- F.BaseOffset, F.HasBaseReg, F.Scale);
+ F.BaseOffset, F.getHasBaseReg(), F.Scale);
}
static bool isLegalAddImmediate(const TargetTransformInfo &TTI,
@@ -1939,15 +1949,15 @@ static bool isAMCompletelyFolded(const TargetTransformInfo &TTI,
if (LU.Kind == LSRUse::Address && TTI.LSRWithInstrQueries()) {
for (const LSRFixup &Fixup : LU.Fixups)
if (!isAMCompletelyFolded(TTI, LSRUse::Address, LU.AccessTy, F.BaseGV,
- (F.BaseOffset + Fixup.Offset), F.HasBaseReg,
- F.Scale, Fixup.UserInst))
+ (F.BaseOffset + Fixup.Offset),
+ F.getHasBaseReg(), F.Scale, Fixup.UserInst))
return false;
return true;
}
return isAMCompletelyFolded(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind,
- LU.AccessTy, F.BaseGV, F.BaseOffset, F.HasBaseReg,
- F.Scale);
+ LU.AccessTy, F.BaseGV, F.BaseOffset,
+ F.getHasBaseReg(), F.Scale);
}
static InstructionCost getScalingFactorCost(const TargetTransformInfo &TTI,
@@ -1975,10 +1985,10 @@ static InstructionCost getScalingFactorCost(const TargetTransformInfo &TTI,
}
InstructionCost ScaleCostMinOffset = TTI.getScalingFactorCost(
LU.AccessTy.MemTy, F.BaseGV, StackOffset::get(FixedMin, ScalableMin),
- F.HasBaseReg, F.Scale, LU.AccessTy.AddrSpace);
+ F.getHasBaseReg(), F.Scale, LU.AccessTy.AddrSpace);
InstructionCost ScaleCostMaxOffset = TTI.getScalingFactorCost(
LU.AccessTy.MemTy, F.BaseGV, StackOffset::get(FixedMax, ScalableMax),
- F.HasBaseReg, F.Scale, LU.AccessTy.AddrSpace);
+ F.getHasBaseReg(), F.Scale, LU.AccessTy.AddrSpace);
assert(ScaleCostMinOffset.isValid() && ScaleCostMaxOffset.isValid() &&
"Legal addressing mode has an illegal cost!");
@@ -2141,9 +2151,15 @@ class LSRInstance {
MemorySSAUpdater *MSSAU;
TTI::AddressingModeKind AMK;
mutable SCEVExpander Rewriter;
- bool Changed = false;
- bool HardwareLoopProfitable = false;
- bool ShouldPreserveLCSSA = false;
+ bool getChangedFlag() const { return IVChainVec.getFlag(0); }
+ bool setChangedFlag(bool Value) {
+ IVChainVec.setFlag(0, Value);
+ return Value;
+ }
+ bool getHardwareLoopProfitable() const { return IVChainVec.getFlag(1); }
+ void setHardwareLoopProfitable(bool Value) { IVChainVec.setFlag(1, Value); }
+ bool getShouldPreserveLCSSA() const { return IVChainVec.getFlag(2); }
+ void setShouldPreserveLCSSA(bool Value) { IVChainVec.setFlag(2, Value); }
/// This is the insert position that the current loop's induction variable
/// increment should be placed. In simple loops, this is the latch block's
@@ -2178,7 +2194,7 @@ class LSRInstance {
static const unsigned MaxChains = 8;
/// IV users can form a chain of IV increments.
- SmallVector<IVChain, MaxChains> IVChainVec;
+ llvm::SmallVectorWithFlags<IVChain, MaxChains, 3> IVChainVec;
/// IV users that belong to profitable IVChains.
SmallPtrSet<Use*, MaxChains> IVIncSet;
@@ -2300,7 +2316,7 @@ class LSRInstance {
TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU,
bool PreserveLCSSA);
- bool getChanged() const { return Changed; }
+ bool getChanged() const { return getChangedFlag(); }
const SmallVectorImpl<WeakVH> &getScalarEvolutionIVs() const {
return ScalarEvolutionIVs;
}
@@ -2429,7 +2445,7 @@ void LSRInstance::OptimizeShadowIV() {
/* Remove cast operation */
ShadowUse->replaceAllUsesWith(NewPH);
ShadowUse->eraseFromParent();
- Changed = true;
+ setChangedFlag(true);
break;
}
}
@@ -2752,7 +2768,7 @@ LSRInstance::OptimizeLoopTermCond() {
// use the post-incremented version of the IV, allowing us to coalesce the
// live ranges for the IV correctly.
CondUse->transformToPostInc(L);
- Changed = true;
+ setChangedFlag(true);
PostIncs.insert(Cond);
decline_post_inc:;
@@ -2888,9 +2904,9 @@ LSRInstance::FindUseWithSimilarFormula(const Formula &OrigF,
for (const Formula &F : LU.Formulae) {
// Check to see if this formula has the same registers and symbols
// as OrigF.
- if (F.BaseRegs == OrigF.BaseRegs &&
- F.ScaledReg == OrigF.ScaledReg &&
- F.BaseGV == OrigF.BaseGV &&
+ if ((llvm::ArrayRef<const llvm::SCEV *>(F.BaseRegs) ==
+ llvm::ArrayRef<const llvm::SCEV *>(OrigF.BaseRegs)) &&
+ F.ScaledReg == OrigF.ScaledReg && F.BaseGV == OrigF.BaseGV &&
F.Scale == OrigF.Scale &&
F.UnfoldedOffset == OrigF.UnfoldedOffset) {
if (F.BaseOffset.isZero())
@@ -3584,7 +3600,7 @@ void LSRInstance::CollectFixupsAndInitialFormulae() {
CI->setOperand(1, CI->getOperand(0));
CI->setOperand(0, NV);
NV = CI->getOperand(1);
- Changed = true;
+ setChangedFlag(true);
}
// x == y --> x - y == 0
@@ -3639,15 +3655,23 @@ void LSRInstance::CollectFixupsAndInitialFormulae() {
LF.OperandValToReplace = U.getOperandValToReplace();
LF.PostIncLoops = TmpPostIncLoops;
LF.Offset = Offset;
- LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
- LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
+ [&] {
+ auto PackedFlagValue = LF.isUseFullyOutsideLoop(L);
+ return LU.setAllFixupsOutsideLoop(LU.getAllFixupsOutsideLoop() &
+ PackedFlagValue);
+ }();
+ [&] {
+ auto PackedFlagValue = IsFixupExecutedEachIncrement(LF);
+ return LU.setAllFixupsUnconditional(LU.getAllFixupsUnconditional() &
+ PackedFlagValue);
+ }();
// Create SCEV as Formula for calculating baseline cost
if (!VisitedLSRUse.count(LUIdx) && !LF.isUseFullyOutsideLoop(L)) {
Formula F;
F.initialMatch(S, L, SE);
BaselineCost.RateFormula(F, Regs, VisitedRegs, LU,
- HardwareLoopProfitable);
+ getHardwareLoopProfitable());
VisitedLSRUse.insert(LUIdx);
}
@@ -3667,7 +3691,7 @@ void LSRInstance::InsertInitialFormula(const SCEV *S, LSRUse &LU,
size_t LUIdx) {
// Mark uses whose expressions cannot be expanded.
if (!Rewriter.isSafeToExpand(S))
- LU.RigidFormula = true;
+ LU.setRigidFormula(true);
Formula F;
F.initialMatch(S, L, SE);
@@ -3682,7 +3706,7 @@ LSRInstance::InsertSupplementalFormula(const SCEV *S,
LSRUse &LU, size_t LUIdx) {
Formula F;
F.BaseRegs.push_back(S);
- F.HasBaseReg = true;
+ F.setHasBaseReg(true);
bool Inserted = InsertFormula(LU, LUIdx, F);
assert(Inserted && "Supplemental formula already exists!"); (void)Inserted;
}
@@ -3839,8 +3863,16 @@ LSRInstance::CollectLoopInvariantFixupsAndFormulae() {
LF.UserInst = const_cast<Instruction *>(UserInst);
LF.OperandValToReplace = U;
LF.Offset = Offset;
- LU.AllFixupsOutsideLoop &= LF.isUseFullyOutsideLoop(L);
- LU.AllFixupsUnconditional &= IsFixupExecutedEachIncrement(LF);
+ [&] {
+ auto PackedFlagValue = LF.isUseFullyOutsideLoop(L);
+ return LU.setAllFixupsOutsideLoop(LU.getAllFixupsOutsideLoop() &
+ PackedFlagValue);
+ }();
+ [&] {
+ auto PackedFlagValue = IsFixupExecutedEachIncrement(LF);
+ return LU.setAllFixupsUnconditional(LU.getAllFixupsUnconditional() &
+ PackedFlagValue);
+ }();
InsertSupplementalFormula(US, LU, LUIdx);
CountRegisters(LU.Formulae.back(), Uses.size() - 1);
break;
@@ -4353,7 +4385,7 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
// Check each interesting stride.
for (int64_t Factor : Factors) {
Base.Scale = Factor;
- Base.HasBaseReg = Base.BaseRegs.size() > 1;
+ Base.setHasBaseReg(Base.BaseRegs.size() > 1);
// Check whether this scale is going to be legal.
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
Base)) {
@@ -4362,20 +4394,20 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
if (LU.Kind == LSRUse::Basic &&
isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LSRUse::Special,
LU.AccessTy, Base) &&
- LU.AllFixupsOutsideLoop)
+ LU.getAllFixupsOutsideLoop())
LU.Kind = LSRUse::Special;
else
continue;
}
// For an ICmpZero, negating a solitary base register won't lead to
// new solutions.
- if (LU.Kind == LSRUse::ICmpZero && !Base.HasBaseReg &&
+ if (LU.Kind == LSRUse::ICmpZero && !Base.getHasBaseReg() &&
Base.BaseOffset.isZero() && !Base.BaseGV)
continue;
// For each addrec base reg, if its loop is current loop, apply the scale.
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Base.BaseRegs[i]);
- if (AR && (AR->getLoop() == L || LU.AllFixupsOutsideLoop)) {
+ if (AR && (AR->getLoop() == L || LU.getAllFixupsOutsideLoop())) {
const SCEV *FactorS = SE.getConstant(IntTy, Factor);
if (FactorS->isZero())
continue;
@@ -4390,12 +4422,13 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
// The canonical representation of 1*reg is reg, which is already in
// Base. In that case, do not try to insert the formula, it will be
// rejected anyway.
- if (F.Scale == 1 && (F.BaseRegs.empty() ||
- (AR->getLoop() != L && LU.AllFixupsOutsideLoop)))
+ if (F.Scale == 1 &&
+ (F.BaseRegs.empty() ||
+ (AR->getLoop() != L && LU.getAllFixupsOutsideLoop())))
continue;
// If AllFixupsOutsideLoop is true and F.Scale is 1, we may generate
// non canonical Formula with ScaledReg's loop not being L.
- if (F.Scale == 1 && LU.AllFixupsOutsideLoop)
+ if (F.Scale == 1 && LU.getAllFixupsOutsideLoop())
F.canonicalize(*L);
(void)InsertFormula(LU, LUIdx, F);
}
@@ -4794,7 +4827,7 @@ void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
// the corresponding bad register from the Regs set.
Cost CostF(Opts, L, SE, TTI, AMK);
Regs.clear();
- CostF.RateFormula(F, Regs, VisitedRegs, LU, HardwareLoopProfitable,
+ CostF.RateFormula(F, Regs, VisitedRegs, LU, getHardwareLoopProfitable(),
&LoserRegs);
if (CostF.isLoser()) {
// During initial formula generation, undesirable formulae are generated
@@ -4829,7 +4862,7 @@ void LSRInstance::FilterOutUndesirableDedicatedRegisters() {
Cost CostBest(Opts, L, SE, TTI, AMK);
Regs.clear();
CostBest.RateFormula(Best, Regs, VisitedRegs, LU,
- HardwareLoopProfitable);
+ getHardwareLoopProfitable());
if (CostF.isLess(CostBest))
std::swap(F, Best);
LLVM_DEBUG(dbgs() << " Filtering out formula "; F.print(dbgs());
@@ -4979,8 +5012,12 @@ void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
LLVM_DEBUG(dbgs() << " Deleting use "; LU.print(dbgs()); dbgs() << '\n');
- LUThatHas->AllFixupsOutsideLoop &= LU.AllFixupsOutsideLoop;
- LUThatHas->AllFixupsUnconditional &= LU.AllFixupsUnconditional;
+ LUThatHas->setAllFixupsOutsideLoop(
+ int(LUThatHas->getAllFixupsOutsideLoop()) &
+ (LU.getAllFixupsOutsideLoop()));
+ LUThatHas->setAllFixupsUnconditional(
+ int(LUThatHas->getAllFixupsUnconditional()) &
+ (LU.getAllFixupsUnconditional()));
// Transfer the fixups of LU to LUThatHas.
for (LSRFixup &Fixup : LU.Fixups) {
@@ -5097,9 +5134,11 @@ void LSRInstance::NarrowSearchSpaceByFilterFormulaWithSameScaledReg() {
Cost CostFA(Opts, L, SE, TTI, AMK);
Cost CostFB(Opts, L, SE, TTI, AMK);
Regs.clear();
- CostFA.RateFormula(FA, Regs, VisitedRegs, LU, HardwareLoopProfitable);
+ CostFA.RateFormula(FA, Regs, VisitedRegs, LU,
+ getHardwareLoopProfitable());
Regs.clear();
- CostFB.RateFormula(FB, Regs, VisitedRegs, LU, HardwareLoopProfitable);
+ CostFB.RateFormula(FB, Regs, VisitedRegs, LU,
+ getHardwareLoopProfitable());
return CostFA.isLess(CostFB);
};
@@ -5203,7 +5242,7 @@ void LSRInstance::NarrowSearchSpaceByMergingUsesOutsideLoop() {
LSRUse &LU = Uses[LUIdx];
// Don't merge ICmpZero uses outside the loop, as ICmpZero needs to be
// handled specially when expanding.
- if (!LU.AllFixupsOutsideLoop || LU.Formulae.empty() ||
+ if (!LU.getAllFixupsOutsideLoop() || LU.Formulae.empty() ||
LU.Kind == LSRUse::ICmpZero)
continue;
@@ -5215,7 +5254,7 @@ void LSRInstance::NarrowSearchSpaceByMergingUsesOutsideLoop() {
const Formula &ThisF = LU.Formulae[0];
for (LSRUse &OtherLU : Uses) {
// Only merge with uses inside the loop
- if (OtherLU.AllFixupsOutsideLoop)
+ if (OtherLU.getAllFixupsOutsideLoop())
continue;
// Can't merge with ICmpZero uses as they're handled specially when
// expanding
@@ -5235,7 +5274,7 @@ void LSRInstance::NarrowSearchSpaceByMergingUsesOutsideLoop() {
// cost may end up being inaccurate, but it's also what we would have
// gotten if we'd ignored uses outside the loop entirely.
const Formula &OtherF = OtherLU.Formulae[0];
- if (ThisF.BaseRegs == OtherF.BaseRegs &&
+ if (ArrayRef(ThisF.BaseRegs) == ArrayRef(OtherF.BaseRegs) &&
ThisF.ScaledReg == OtherF.ScaledReg &&
ThisF.BaseGV == OtherF.BaseGV && ThisF.Scale == OtherF.Scale &&
ThisF.UnfoldedOffset == OtherF.UnfoldedOffset &&
@@ -5579,7 +5618,8 @@ void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution,
// the current best, prune the search at that point.
NewCost = CurCost;
NewRegs = CurRegs;
- NewCost.RateFormula(F, NewRegs, VisitedRegs, LU, HardwareLoopProfitable);
+ NewCost.RateFormula(F, NewRegs, VisitedRegs, LU,
+ getHardwareLoopProfitable());
if (NewCost.isLess(SolutionCost)) {
Workspace.push_back(&F);
if (Workspace.size() != Uses.size()) {
@@ -5773,7 +5813,7 @@ BasicBlock::iterator LSRInstance::AdjustInsertPositionForExpand(
Value *LSRInstance::Expand(const LSRUse &LU, const LSRFixup &LF,
const Formula &F, BasicBlock::iterator IP,
SmallVectorImpl<WeakTrackingVH> &DeadInsts) const {
- if (LU.RigidFormula)
+ if (LU.getRigidFormula())
return LF.OperandValToReplace;
// Determine an input position which will be dominated by the operands and
@@ -5993,7 +6033,7 @@ void LSRInstance::RewriteForPHI(PHINode *PN, const LSRUse &LU,
CriticalEdgeSplittingOptions SplitOptions(&DT, &LI, MSSAU);
SplitOptions =
SplitOptions.setMergeIdenticalEdges().setKeepOneInputPHIs();
- if (ShouldPreserveLCSSA)
+ if (getShouldPreserveLCSSA())
SplitOptions = SplitOptions.setPreserveLCSSA();
NewBB = SplitCriticalEdge(BB, Parent, SplitOptions);
} else {
@@ -6180,7 +6220,7 @@ void LSRInstance::ImplementSolution(
getFixupInsertPos(TTI, Fixup, Uses[LUIdx], IVIncInsertPos, DT);
Rewriter.setIVIncInsertPos(L, InsertPos);
Rewrite(Uses[LUIdx], Fixup, *Solution[LUIdx], DeadInsts);
- Changed = true;
+ setChangedFlag(true);
}
auto InsertedInsts = InsertedNonLCSSAInsts.takeVector();
@@ -6188,7 +6228,7 @@ void LSRInstance::ImplementSolution(
for (const IVChain &Chain : IVChainVec) {
GenerateIVChain(Chain, DeadInsts);
- Changed = true;
+ setChangedFlag(true);
}
for (const WeakVH &IV : Rewriter.getInsertedIVs())
@@ -6199,8 +6239,12 @@ void LSRInstance::ImplementSolution(
// instructions.
Rewriter.clear();
- Changed |= RecursivelyDeleteTriviallyDeadInstructionsPermissive(DeadInsts,
- &TLI, MSSAU);
+ [&] {
+ auto PackedFlagValue_ =
+ RecursivelyDeleteTriviallyDeadInstructionsPermissive(DeadInsts, &TLI,
+ MSSAU);
+ return setChangedFlag(getChangedFlag() | PackedFlagValue_);
+ }();
// In our cost analysis above, we assume that each addrec consumes exactly
// one register, and arrange to have increments inserted just before the
@@ -6241,7 +6285,7 @@ void LSRInstance::ImplementSolution(
[&](Use &U) {return DT.dominates(IVIncInsertPos, U);}))
continue;
BO->moveBefore(IVIncInsertPos->getIterator());
- Changed = true;
+ setChangedFlag(true);
}
@@ -6255,8 +6299,9 @@ LSRInstance::LSRInstance(const ScalarOptions &Opts, Loop *L, IVUsers &IU,
: Opts(Opts), IU(IU), SE(SE), DT(DT), LI(LI), AC(AC), TLI(TLI), TTI(TTI),
L(L), MSSAU(MSSAU), AMK(Opts.lsr_preferred_addressing_mode.value_or(
TTI.getPreferredAddressingMode(L, &SE))),
- Rewriter(SE, "lsr", PreserveLCSSA), ShouldPreserveLCSSA(PreserveLCSSA),
- BaselineCost(Opts, L, SE, TTI, AMK) {
+ Rewriter(SE, "lsr", PreserveLCSSA), BaselineCost(Opts, L, SE, TTI, AMK),
+ IVChainVec(decltype(this->IVChainVec)::withFlags(
+ (unsigned(PreserveLCSSA) << 2))) {
// If LoopSimplify form is not available, stay out of trouble.
if (!L->isLoopSimplifyForm())
return;
@@ -6294,8 +6339,8 @@ LSRInstance::LSRInstance(const ScalarOptions &Opts, Loop *L, IVUsers &IU,
// Check if we expect this loop to use a hardware loop instruction, which will
// be used when calculating the costs of formulas.
HardwareLoopInfo HWLoopInfo(L);
- HardwareLoopProfitable =
- TTI.isHardwareLoopProfitable(L, SE, AC, &TLI, HWLoopInfo);
+ setHardwareLoopProfitable(
+ TTI.isHardwareLoopProfitable(L, SE, AC, &TLI, HWLoopInfo));
// Configure SCEVExpander already now, so the correct mode is used for
// isSafeToExpand() checks.
@@ -6759,14 +6804,16 @@ struct SCEVDbgValueBuilder {
/// and DIExpression.
struct DVIRecoveryRec {
DVIRecoveryRec(DbgVariableRecord *DVR)
- : DbgRef(DVR), Expr(DVR->getExpression()), HadLocationArgList(false) {}
+ : DbgRef(DVR), Expr(DVR->getExpression()) {}
DbgVariableRecord *DbgRef;
DIExpression *Expr;
- bool HadLocationArgList;
+ bool getHadLocationArgList() const { return RecoveryExprs.getFlag(0); }
+ void setHadLocationArgList(bool Value) { RecoveryExprs.setFlag(0, Value); }
SmallVector<WeakVH, 2> LocationOps;
SmallVector<const llvm::SCEV *, 2> SCEVs;
- SmallVector<std::unique_ptr<SCEVDbgValueBuilder>, 2> RecoveryExprs;
+ llvm::SmallVectorWithFlags<std::unique_ptr<SCEVDbgValueBuilder>, 2>
+ RecoveryExprs;
void clear() {
for (auto &RE : RecoveryExprs)
@@ -6872,7 +6919,7 @@ static void restorePreTransformState(DVIRecoveryRec &DVIRec) {
// Even a single location-op may be inside a DIArgList and referenced with
// DW_OP_LLVM_arg, which is valid only with a DIArgList.
- if (!DVIRec.HadLocationArgList) {
+ if (!DVIRec.getHadLocationArgList()) {
assert(DVIRec.LocationOps.size() == 1 &&
"Unexpected number of location ops.");
// LSR's unsuccessful salvage attempt may have added DIArgList, which in
@@ -7083,7 +7130,10 @@ static void DbgGatherSalvagableDVI(
for (const auto LocOp : DbgVal.location_ops()) {
NewRec->SCEVs.push_back(SE.getSCEV(LocOp));
NewRec->LocationOps.push_back(LocOp);
- NewRec->HadLocationArgList = DbgVal.hasArgList();
+ [&] {
+ auto PackedFlagValue_ = DbgVal.hasArgList();
+ return NewRec->setHadLocationArgList(PackedFlagValue_);
+ }();
}
SalvageableDVISCEVs.push_back(std::move(NewRec));
}
diff --git a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
index 44af9c7dbc976..efd523db4fe36 100644
--- a/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
+++ b/llvm/lib/Transforms/Scalar/LowerMatrixIntrinsics.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/DomTreeUpdater.h"
@@ -380,17 +381,27 @@ class LowerMatrixIntrinsics {
/// Wrapper class representing a matrix as a set of vectors, either in row or
/// column major layout. All vectors must have the same vector type.
class MatrixTy {
- SmallVector<Value *, 16> Vectors;
+ llvm::SmallVectorWithFlags<Value *, 16> Vectors;
OpInfoTy OpInfo;
- bool IsColumnMajor = ScalarOptions::Global.matrix_default_layout ==
- MatrixLayoutTy::ColumnMajor;
+ bool getIsColumnMajor() const { return Vectors.getFlag(0); }
+ void setIsColumnMajor(bool Value) { Vectors.setFlag(0, Value); }
public:
- MatrixTy() = default;
- MatrixTy(ArrayRef<Value *> Vectors) : Vectors(Vectors) {}
- MatrixTy(unsigned NumRows, unsigned NumColumns, Type *EltTy) {
+ MatrixTy()
+ : Vectors(decltype(this->Vectors)::withFlags(
+ unsigned(bool(ScalarOptions::Global.matrix_default_layout ==
+ MatrixLayoutTy::ColumnMajor)))) {}
+ MatrixTy(ArrayRef<Value *> Vectors)
+ : Vectors(decltype(this->Vectors)::withFlags(
+ unsigned(bool(ScalarOptions::Global.matrix_default_layout ==
+ MatrixLayoutTy::ColumnMajor)),
+ Vectors)) {}
+ MatrixTy(unsigned NumRows, unsigned NumColumns, Type *EltTy)
+ : Vectors(decltype(this->Vectors)::withFlags(
+ unsigned(bool(ScalarOptions::Global.matrix_default_layout ==
+ MatrixLayoutTy::ColumnMajor)))) {
unsigned D = isColumnMajor() ? NumColumns : NumRows;
for (unsigned J = 0; J < D; ++J)
@@ -489,7 +500,7 @@ class LowerMatrixIntrinsics {
const OpInfoTy &getOpInfo() const { return OpInfo; }
- bool isColumnMajor() const { return IsColumnMajor; }
+ bool isColumnMajor() const { return getIsColumnMajor(); }
unsigned getStride() const {
if (isColumnMajor())
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index e6407049899ec..f59abaf7b6886 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -33,6 +33,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
@@ -172,8 +173,8 @@ class SROA {
LLVMContext *const C;
DomTreeUpdater *const DTU;
AssumptionCache *const AC;
- const bool PreserveCFG;
- const bool AggregateToVector;
+ bool getPreserveCFG() const { return DeadInsts.getFlag(0); }
+ bool getAggregateToVector() const { return DeadInsts.getFlag(1); }
/// Worklist of alloca instructions to simplify.
///
@@ -187,7 +188,7 @@ class 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;
+ llvm::SmallVectorWithFlags<WeakVH, 8, 2> DeadInsts;
/// Post-promotion worklist.
///
@@ -243,8 +244,9 @@ class SROA {
SROA(LLVMContext *C, DomTreeUpdater *DTU, AssumptionCache *AC,
SROAOptions Options)
: C(C), DTU(DTU), AC(AC),
- PreserveCFG(Options.CFG == SROAOptions::PreserveCFG),
- AggregateToVector(Options.AggregateToVector) {}
+ DeadInsts(decltype(this->DeadInsts)::withFlags(
+ unsigned(bool(Options.CFG == SROAOptions::PreserveCFG)) |
+ (unsigned(bool(Options.AggregateToVector)) << 1))) {}
/// Main run method used by both the SROAPass and by the legacy pass.
std::pair<bool /*Changed*/, bool /*CFGChanged*/> runSROA(Function &F);
@@ -1116,7 +1118,7 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
// If there is a load with an unknown offset, we can still perform store
// to load forwarding for other known-offset loads.
- if (!IsOffsetKnown)
+ if (!isOffsetKnown())
return PI.setEscapedReadOnly(&LI);
TypeSize Size = DL.getTypeStoreSize(LI.getType());
@@ -1136,7 +1138,7 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
Value *ValOp = SI.getValueOperand();
if (ValOp == *U)
return PI.setEscapedAndAborted(&SI);
- if (!IsOffsetKnown)
+ if (!isOffsetKnown())
return PI.setAborted(&SI);
TypeSize StoreSize = DL.getTypeStoreSize(ValOp->getType());
@@ -1175,11 +1177,11 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
assert(II.getRawDest() == *U && "Pointer use is not the destination?");
ConstantInt *Length = dyn_cast<ConstantInt>(II.getLength());
if ((Length && Length->getValue() == 0) ||
- (IsOffsetKnown && Offset.uge(AllocSize)))
+ (isOffsetKnown() && Offset.uge(AllocSize)))
// Zero-length mem transfer intrinsics can be ignored entirely.
return markAsDead(II);
- if (!IsOffsetKnown)
+ if (!isOffsetKnown())
return PI.setAborted(&II);
insertUse(II, Offset,
@@ -1199,7 +1201,7 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
if (VisitedDeadInsts.count(&II))
return;
- if (!IsOffsetKnown)
+ if (!isOffsetKnown())
return PI.setAborted(&II);
// This side of the transfer is completely out-of-bounds, and so we can
@@ -1266,7 +1268,7 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
return;
}
- if (!IsOffsetKnown)
+ if (!isOffsetKnown())
return PI.setAborted(&II);
if (II.isLifetimeStartOrEnd()) {
@@ -1364,7 +1366,7 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
return;
}
- if (!IsOffsetKnown)
+ if (!isOffsetKnown())
return PI.setAborted(&I);
// See if we already have computed info on this node.
@@ -5721,7 +5723,7 @@ SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, Partition &P) {
const DataLayout &DL = AI.getDataLayout();
// Select the type for the new alloca that spans the partition.
auto [PartitionTy, IsIntegerWideningViable, VecTy] =
- selectPartitionType(P, DL, AI, *C, AggregateToVector);
+ selectPartitionType(P, DL, AI, *C, getAggregateToVector());
// Check for the case where we're going to rewrite to a new alloca of the
// exact same type as the original, and with the same access offsets. In that
@@ -5791,7 +5793,7 @@ SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, Partition &P) {
NewSpeculatablePHIs.push_back(PHI);
continue;
}
- if (getPHIStoreToRewrite(*PHI, PreserveCFG, DTU->getDomTree())) {
+ if (getPHIStoreToRewrite(*PHI, getPreserveCFG(), DTU->getDomTree())) {
NewPHIsWithStoreToRewrite.push_back(PHI);
continue;
}
@@ -5806,7 +5808,7 @@ SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, Partition &P) {
NewSelectsToRewrite.reserve(SelectUsers.size());
for (SelectInst *Sel : SelectUsers) {
std::optional<RewriteableMemOps> Ops =
- isSafeSelectToSpeculate(*Sel, PreserveCFG);
+ isSafeSelectToSpeculate(*Sel, getPreserveCFG());
if (!Ops) {
Promotable = false;
break;
@@ -6410,7 +6412,7 @@ SROA::runOnAlloca(AllocaInst &AI) {
while (!RemainingSelectsToRewrite.empty()) {
const auto [K, V] = RemainingSelectsToRewrite.pop_back_val();
CFGChanged |=
- rewriteSelectInstMemOps(*K, V, IRB, PreserveCFG ? nullptr : DTU);
+ rewriteSelectInstMemOps(*K, V, IRB, getPreserveCFG() ? nullptr : DTU);
}
return {Changed, CFGChanged};
@@ -6529,7 +6531,7 @@ std::pair<bool /*Changed*/, bool /*CFGChanged*/> SROA::runSROA(Function &F) {
} while (!Worklist.empty());
assert((!CFGChanged || Changed) && "Can not only modify the CFG.");
- assert((!CFGChanged || !PreserveCFG) &&
+ assert((!CFGChanged || !getPreserveCFG()) &&
"Should not have modified the CFG when told to preserve it.");
if (Changed && isAssignmentTrackingEnabled(*F.getParent())) {
diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp
index 080c88d1cd951..9d08745a867cc 100644
--- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp
+++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp
@@ -17,6 +17,7 @@
#include "llvm/Transforms/Scalar/Scalarizer.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/VectorUtils.h"
@@ -119,9 +120,10 @@ class Scatterer {
BasicBlock::iterator BBI;
Value *V;
VectorSplit VS;
- bool IsPointer;
+ bool getIsPointer() const { return Tmp.getFlag(0); }
+ void setIsPointer(bool Value) { Tmp.setFlag(0, Value); }
ValueVector *CachePtr;
- ValueVector Tmp;
+ llvm::SmallVectorWithFlagsFor<ValueVector, 1> Tmp;
};
// FCmpSplitter(FCI)(Builder, X, Y, Name) uses Builder to create an FCmp
@@ -278,10 +280,10 @@ class ScalarizerVisitor : public InstVisitor<ScalarizerVisitor, bool> {
public:
ScalarizerVisitor(DominatorTree *DT, const TargetTransformInfo *TTI,
ScalarizerPassOptions Options)
- : DT(DT), TTI(TTI),
- ScalarizeVariableInsertExtract(Options.ScalarizeVariableInsertExtract),
- ScalarizeLoadStore(Options.ScalarizeLoadStore),
- ScalarizeMinBits(Options.ScalarizeMinBits) {}
+ : Gathered(decltype(this->Gathered)::withFlags(
+ (unsigned(bool(Options.ScalarizeVariableInsertExtract)) << 1) |
+ (unsigned(bool(Options.ScalarizeLoadStore)) << 2))),
+ DT(DT), TTI(TTI), ScalarizeMinBits(Options.ScalarizeMinBits) {}
bool visit(Function &F);
@@ -323,16 +325,17 @@ class ScalarizerVisitor : public InstVisitor<ScalarizerVisitor, bool> {
bool splitCall(CallInst &CI);
ScatterMap Scattered;
- GatherList Gathered;
- bool Scalarized;
+ llvm::SmallVectorWithFlagsFor<GatherList, 3> Gathered;
+ bool getScalarized() const { return Gathered.getFlag(0); }
+ void setScalarized(bool Value) { Gathered.setFlag(0, Value); }
SmallVector<WeakTrackingVH, 32> PotentiallyDeadInstrs;
DominatorTree *DT;
const TargetTransformInfo *TTI;
- const bool ScalarizeVariableInsertExtract;
- const bool ScalarizeLoadStore;
+ bool getScalarizeVariableInsertExtract() const { return Gathered.getFlag(1); }
+ bool getScalarizeLoadStore() const { return Gathered.getFlag(2); }
const unsigned ScalarizeMinBits;
};
@@ -368,12 +371,12 @@ INITIALIZE_PASS_END(ScalarizerLegacyPass, "scalarizer",
Scatterer::Scatterer(BasicBlock::iterator bbi, Value *v, const VectorSplit &VS,
ValueVector *cachePtr)
: BBI(bbi), V(v), VS(VS), CachePtr(cachePtr) {
- IsPointer = V->getType()->isPointerTy();
+ setIsPointer(V->getType()->isPointerTy());
if (!CachePtr) {
Tmp.resize(VS.NumFragments, nullptr);
} else {
assert((CachePtr->empty() || VS.NumFragments == CachePtr->size() ||
- IsPointer) &&
+ getIsPointer()) &&
"Inconsistent vector sizes");
if (VS.NumFragments > CachePtr->size())
CachePtr->resize(VS.NumFragments, nullptr);
@@ -382,12 +385,13 @@ Scatterer::Scatterer(BasicBlock::iterator bbi, Value *v, const VectorSplit &VS,
// Return fragment Frag, creating a new Value for it if necessary.
Value *Scatterer::operator[](unsigned Frag) {
- ValueVector &CV = CachePtr ? *CachePtr : Tmp;
+ MutableArrayRef<Value *> CV = CachePtr ? MutableArrayRef<Value *>(*CachePtr)
+ : MutableArrayRef<Value *>(Tmp);
// Try to reuse a previous value.
if (CV[Frag])
return CV[Frag];
IRBuilder<> Builder(BBI);
- if (IsPointer) {
+ if (getIsPointer()) {
if (Frag == 0)
CV[Frag] = V;
else
@@ -455,7 +459,7 @@ FunctionPass *llvm::createScalarizerPass(const ScalarizerPassOptions &Options) {
bool ScalarizerVisitor::visit(Function &F) {
assert(Gathered.empty() && Scattered.empty());
- Scalarized = false;
+ setScalarized(false);
// To ensure we replace gathered components correctly we need to do an ordered
// traversal of the basic blocks in the function.
@@ -467,7 +471,7 @@ bool ScalarizerVisitor::visit(Function &F) {
++II;
if (Done && I->getType()->isVoidTy()) {
I->eraseFromParent();
- Scalarized = true;
+ setScalarized(true);
}
}
}
@@ -538,7 +542,7 @@ void ScalarizerVisitor::replaceUses(Instruction *Op, Value *CV) {
if (CV != Op) {
Op->replaceAllUsesWith(CV);
PotentiallyDeadInstrs.emplace_back(Op);
- Scalarized = true;
+ setScalarized(true);
}
}
@@ -1091,7 +1095,7 @@ bool ScalarizerVisitor::visitInsertElementInst(InsertElementInst &IEI) {
}
} else {
// Never split a variable insertelement that isn't fully scalarized.
- if (!ScalarizeVariableInsertExtract || VS->NumPacked > 1)
+ if (!getScalarizeVariableInsertExtract() || VS->NumPacked > 1)
return false;
for (unsigned I = 0; I < VS->NumFragments; ++I) {
@@ -1184,7 +1188,7 @@ bool ScalarizerVisitor::visitExtractElementInst(ExtractElementInst &EEI) {
}
// Never split a variable extractelement that isn't fully scalarized.
- if (!ScalarizeVariableInsertExtract || VS->NumPacked > 1)
+ if (!getScalarizeVariableInsertExtract() || VS->NumPacked > 1)
return false;
Value *Res = PoisonValue::get(VS->VecTy->getElementType());
@@ -1251,7 +1255,7 @@ bool ScalarizerVisitor::visitPHINode(PHINode &PHI) {
}
bool ScalarizerVisitor::visitLoadInst(LoadInst &LI) {
- if (!ScalarizeLoadStore)
+ if (!getScalarizeLoadStore())
return false;
if (!LI.isSimple())
return false;
@@ -1276,7 +1280,7 @@ bool ScalarizerVisitor::visitLoadInst(LoadInst &LI) {
}
bool ScalarizerVisitor::visitStoreInst(StoreInst &SI) {
- if (!ScalarizeLoadStore)
+ if (!getScalarizeLoadStore())
return false;
if (!SI.isSimple())
return false;
@@ -1318,7 +1322,7 @@ bool ScalarizerVisitor::visitFreezeInst(FreezeInst &FI) {
bool ScalarizerVisitor::finish() {
// The presence of data in Gathered or Scattered indicates changes
// made to the Function.
- if (Gathered.empty() && Scattered.empty() && !Scalarized)
+ if (Gathered.empty() && Scattered.empty() && !getScalarized())
return false;
for (const auto &GMI : Gathered) {
Instruction *Op = GMI.first;
@@ -1380,7 +1384,7 @@ bool ScalarizerVisitor::finish() {
}
Gathered.clear();
Scattered.clear();
- Scalarized = false;
+ setScalarized(false);
RecursivelyDeleteTriviallyDeadInstructionsPermissive(PotentiallyDeadInstrs);
diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
index f891bf693b560..57b02532c5457 100644
--- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -53,6 +53,7 @@
#include "ScalarOptions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
@@ -482,7 +483,7 @@ class TailRecursionEliminator {
DomTreeUpdater &DTU;
BlockFrequencyInfo *const BFI;
ProfileSummaryInfo *const PSI;
- const bool UpdateFunctionEntryCount;
+ bool getUpdateFunctionEntryCount() const { return RetSelects.getFlag(0); }
const uint64_t OrigEntryBBFreq;
const uint64_t OrigEntryCount;
@@ -500,7 +501,7 @@ class TailRecursionEliminator {
// Vector of select instructions we insereted. These selects use RetKnownPN
// to either propagate RetPN or select a new return value.
- SmallVector<SelectInst *, 8> RetSelects;
+ llvm::SmallVectorWithFlags<SelectInst *, 8> RetSelects;
// Keep track of the sum of frequencies of blocks that have calls eliminated
// so we can synthesize branch weights later that require information on
@@ -525,10 +526,12 @@ class TailRecursionEliminator {
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI,
bool UpdateFunctionEntryCount)
: Opts(Opts), F(F), TTI(TTI), AA(AA), ORE(ORE), DTU(DTU), BFI(BFI),
- PSI(PSI), UpdateFunctionEntryCount(UpdateFunctionEntryCount),
+ PSI(PSI),
OrigEntryBBFreq(
BFI ? BFI->getBlockFreq(&F.getEntryBlock()).getFrequency() : 0U),
- OrigEntryCount(F.getEntryCount() ? *F.getEntryCount() : 0) {
+ OrigEntryCount(F.getEntryCount() ? *F.getEntryCount() : 0),
+ RetSelects(decltype(this->RetSelects)::withFlags(
+ unsigned(UpdateFunctionEntryCount))) {
if (BFI) {
// The assert is meant as API documentation for the caller.
assert(OrigEntryBBFreq != 0 &&
@@ -966,7 +969,7 @@ bool TailRecursionEliminator::eliminateCall(CallInst *CI) {
CI->eraseFromParent(); // Remove call.
DTU.applyUpdates({{DominatorTree::Insert, BB, HeaderBB}});
++NumEliminated;
- if (!Opts.tre_disable_entrycount_recompute && UpdateFunctionEntryCount &&
+ if (!Opts.tre_disable_entrycount_recompute && getUpdateFunctionEntryCount() &&
OrigEntryBBFreq) {
assert(F.getEntryCount().has_value());
// This pass is not expected to remove BBs, only add an entry BB. For that
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index aad520d25212a..08207de4887f9 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -271,12 +271,15 @@ CodeExtractor::CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT,
ArrayRef<BasicBlock *> DeallocationBlocks,
std::string Suffix, bool ArgsInZeroAddressSpace,
bool VoidReturnWithSingleOutput)
- : DT(DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
- BPI(BPI), AC(AC), AllocationBlock(AllocationBlock),
- DeallocationBlocks(DeallocationBlocks), AllowVarArgs(AllowVarArgs),
+ : DT(DT), BFI(BFI), BPI(BPI), AC(AC), AllocationBlock(AllocationBlock),
+ DeallocationBlocks(DeallocationBlocks),
Blocks(buildExtractionBlockSet(BBs, DT, AllowVarArgs, AllowAlloca)),
- Suffix(Suffix), ArgsInZeroAddressSpace(ArgsInZeroAddressSpace),
- VoidReturnWithSingleOutput(VoidReturnWithSingleOutput) {}
+ ExtractedFuncRetVals(decltype(this->ExtractedFuncRetVals)::withFlags(
+ unsigned(bool(AggregateArgs || AggregateArgsOpt)) |
+ (unsigned(AllowVarArgs) << 1) |
+ (unsigned(ArgsInZeroAddressSpace) << 2) |
+ (unsigned(VoidReturnWithSingleOutput) << 3))),
+ Suffix(Suffix) {}
/// definedInRegion - Return true if the specified value is defined in the
/// extracted region.
@@ -460,7 +463,8 @@ Instruction *CodeExtractor::allocateVar(IRBuilder<>::InsertPoint AllocaIP,
Instruction *Alloca =
new AllocaInst(VarType, DL.getAllocaAddrSpace(), nullptr, Name, AllocaIP);
- if (CastedAlloc && ArgsInZeroAddressSpace && DL.getAllocaAddrSpace() != 0) {
+ if (CastedAlloc && getArgsInZeroAddressSpace() &&
+ DL.getAllocaAddrSpace() != 0) {
*CastedAlloc = new AddrSpaceCastInst(
Alloca, PointerType::get(BB->getContext(), 0), Name + ".ascast");
(*CastedAlloc)->insertAfter(Alloca->getIterator());
@@ -654,7 +658,7 @@ bool CodeExtractor::isEligible() const {
// For functions with varargs, check that varargs handling is only done in the
// outlined function, i.e vastart and vaend are only used in outlined blocks.
- if (AllowVarArgs && F->getFunctionType()->isVarArg()) {
+ if (getAllowVarArgs() && F->getFunctionType()->isVarArg()) {
auto containsVarArgIntrinsic = [](const Instruction &I) {
if (const CallInst *CI = dyn_cast<CallInst>(&I))
if (const Function *Callee = CI->getCalledFunction())
@@ -717,8 +721,8 @@ void CodeExtractor::findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs,
// Reset stale state from any prior call in HotColdSplitting; the CFG may
// have changed since.
FuncRetVal = nullptr;
- if (!VoidReturnWithSingleOutput && !AggregateArgs && Outputs.size() == 1 &&
- getCommonExitBlock(Blocks)) {
+ if (!getVoidReturnWithSingleOutput() && !getAggregateArgs() &&
+ Outputs.size() == 1 && getCommonExitBlock(Blocks)) {
FuncRetVal = Outputs[0];
Outputs.clear();
}
@@ -885,7 +889,7 @@ Function *CodeExtractor::constructFunctionDeclaration(
// Add the types of the input values to the function's argument list
for (Value *value : inputs) {
LLVM_DEBUG(dbgs() << "value used in func: " << *value << "\n");
- if (AggregateArgs && !ExcludeArgsFromAggregate.contains(value)) {
+ if (getAggregateArgs() && !ExcludeArgsFromAggregate.contains(value)) {
AggParamTy.push_back(value->getType());
StructValues.insert(value);
} else
@@ -895,7 +899,7 @@ Function *CodeExtractor::constructFunctionDeclaration(
// Add the types of the output values to the function's argument list.
for (Value *output : outputs) {
LLVM_DEBUG(dbgs() << "instr used in func: " << *output << "\n");
- if (AggregateArgs && !ExcludeArgsFromAggregate.contains(output)) {
+ if (getAggregateArgs() && !ExcludeArgsFromAggregate.contains(output)) {
AggParamTy.push_back(output->getType());
StructValues.insert(output);
} else
@@ -907,14 +911,15 @@ Function *CodeExtractor::constructFunctionDeclaration(
(ParamTy.size() + AggParamTy.size()) ==
(inputs.size() + outputs.size()) &&
"Number of scalar and aggregate params does not match inputs, outputs");
- assert((StructValues.empty() || AggregateArgs) &&
+ assert((StructValues.empty() || getAggregateArgs()) &&
"Expeced StructValues only with AggregateArgs set");
// Concatenate scalar and aggregate params in ParamTy.
if (!AggParamTy.empty()) {
StructTy = StructType::get(M->getContext(), AggParamTy);
ParamTy.push_back(PointerType::get(
- M->getContext(), ArgsInZeroAddressSpace ? 0 : DL.getAllocaAddrSpace()));
+ M->getContext(),
+ getArgsInZeroAddressSpace() ? 0 : DL.getAllocaAddrSpace()));
}
Type *RetTy = FuncRetVal ? FuncRetVal->getType() : getSwitchType();
@@ -926,7 +931,7 @@ Function *CodeExtractor::constructFunctionDeclaration(
});
FunctionType *funcType = FunctionType::get(
- RetTy, ParamTy, AllowVarArgs && oldFunction->isVarArg());
+ RetTy, ParamTy, getAllowVarArgs() && oldFunction->isVarArg());
// Create the new function
Function *newFunction =
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 41c3c2c3c0e19..03aae472103ef 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -2881,7 +2881,7 @@ void llvm::InlineFunctionImpl(CallBase &CB, InlineFunctionInfo &IFI,
// inlining, the context-sensitive inlinee profile doesn't need to be
// subtracted from callee profile, and the inlined clone also doesn't need
// to be scaled based on call site count.
- if (IFI.UpdateProfile) {
+ if (IFI.getUpdateProfile()) {
if (IFI.CallerBFI != nullptr && IFI.CalleeBFI != nullptr)
// Update the BFI of blocks cloned into the caller.
updateCallerBFI(OrigBB, VMap, IFI.CallerBFI, IFI.CalleeBFI,
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp
index 3c58c381985f1..74f8a55e88da7 100644
--- a/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -2386,8 +2386,11 @@ llvm::hasPartialIVCondition(const Loop &L, unsigned MSSAThreshold,
WorkList.push_back(Header);
SmallPtrSet<BasicBlock *, 4> Seen;
Seen.insert(Header);
- Info.PathIsNoop &=
- all_of(*Header, [](Instruction &I) { return !I.mayHaveSideEffects(); });
+ [&] {
+ auto PackedFlagValue = all_of(
+ *Header, [](Instruction &I) { return !I.mayHaveSideEffects(); });
+ return Info.setPathIsNoop(Info.getPathIsNoop() & PackedFlagValue);
+ }();
while (!WorkList.empty()) {
BasicBlock *Current = WorkList.pop_back_val();
@@ -2397,8 +2400,11 @@ llvm::hasPartialIVCondition(const Loop &L, unsigned MSSAThreshold,
if (!SeenIns.second)
continue;
- Info.PathIsNoop &= all_of(
- *Current, [](Instruction &I) { return !I.mayHaveSideEffects(); });
+ [&] {
+ auto PackedFlagValue = all_of(
+ *Current, [](Instruction &I) { return !I.mayHaveSideEffects(); });
+ return Info.setPathIsNoop(Info.getPathIsNoop() & PackedFlagValue);
+ }();
WorkList.append(succ_begin(Current), succ_end(Current));
}
@@ -2442,12 +2448,15 @@ llvm::hasPartialIVCondition(const Loop &L, unsigned MSSAThreshold,
// We could also allow loops with known trip counts without mustprogress,
// but ScalarEvolution may not be available.
- Info.PathIsNoop &= isMustProgress(&L);
+ [&] {
+ auto PackedFlagValue = isMustProgress(&L);
+ return Info.setPathIsNoop(Info.getPathIsNoop() & PackedFlagValue);
+ }();
// If the path is considered a no-op so far, check if it reaches a
// single exit block without any phis. This ensures no values from the
// loop are used outside of the loop.
- if (Info.PathIsNoop) {
+ if (Info.getPathIsNoop()) {
for (auto *Exiting : ExitingBlocks) {
if (!Seen.contains(Exiting))
continue;
@@ -2455,9 +2464,13 @@ llvm::hasPartialIVCondition(const Loop &L, unsigned MSSAThreshold,
if (L.contains(Succ))
continue;
- Info.PathIsNoop &= Succ->phis().empty() &&
- (!Info.ExitForPath || Info.ExitForPath == Succ);
- if (!Info.PathIsNoop)
+ [&] {
+ auto PackedFlagValue =
+ Succ->phis().empty() &&
+ (!Info.ExitForPath || Info.ExitForPath == Succ);
+ return Info.setPathIsNoop(Info.getPathIsNoop() & PackedFlagValue);
+ }();
+ if (!Info.getPathIsNoop())
break;
assert((!Info.ExitForPath || Info.ExitForPath == Succ) &&
"cannot have multiple exit blocks");
@@ -2466,9 +2479,9 @@ llvm::hasPartialIVCondition(const Loop &L, unsigned MSSAThreshold,
}
}
if (!Info.ExitForPath)
- Info.PathIsNoop = false;
+ Info.setPathIsNoop(false);
- Info.InstToDuplicate = std::move(InstToDuplicate);
+ Info.InstToDuplicate.assign(std::move(InstToDuplicate));
return Info;
};
diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
index ebca42f0e4757..a23e05601826b 100644
--- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
+++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
@@ -31,7 +31,7 @@ namespace memtag {
void forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT,
const LoopInfo &LI, const AllocaInfo &AInfo,
- const SmallVectorImpl<Instruction *> &RetVec,
+ ArrayRef<Instruction *> RetVec,
llvm::function_ref<void(Instruction *)> Callback) {
if (AInfo.LifetimeEnd.size() == 1 && AInfo.LifetimeStart.size() == 1 &&
PDT.dominates(AInfo.LifetimeEnd[0], AInfo.LifetimeStart[0])) {
@@ -121,7 +121,7 @@ void StackInfoBuilder::visit(OptimizationRemarkEmitter &ORE,
if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
if (CI->canReturnTwice()) {
- Info.CallsReturnTwice = true;
+ Info.setCallsReturnTwice(true);
}
}
if (AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 157c3de56be02..baf5b633f0806 100644
--- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/AssumptionCache.h"
@@ -204,11 +205,12 @@ struct AllocaInfo {
using DPUserVec = SmallVector<DbgVariableRecord *, 1>;
SmallVector<BasicBlock *, 32> DefiningBlocks;
- SmallVector<BasicBlock *, 32> UsingBlocks;
+ llvm::SmallVectorWithFlags<BasicBlock *, 32> UsingBlocks;
StoreInst *OnlyStore;
BasicBlock *OnlyBlock;
- bool OnlyUsedInOneBlock;
+ bool getOnlyUsedInOneBlock() const { return UsingBlocks.getFlag(0); }
+ void setOnlyUsedInOneBlock(bool Value) { UsingBlocks.setFlag(0, Value); }
/// The type used by all loads/stores of this alloca. This may differ from
/// the alloca's declared type if all accesses use a different type.
@@ -224,7 +226,7 @@ struct AllocaInfo {
UsingBlocks.clear();
OnlyStore = nullptr;
OnlyBlock = nullptr;
- OnlyUsedInOneBlock = true;
+ setOnlyUsedInOneBlock(true);
ValueType = nullptr;
DPUsers.clear();
AssignmentTracking.clear();
@@ -262,11 +264,11 @@ struct AllocaInfo {
"All loads where checked to have used the same type");
}
- if (OnlyUsedInOneBlock) {
+ if (getOnlyUsedInOneBlock()) {
if (!OnlyBlock)
OnlyBlock = User->getParent();
else if (OnlyBlock != User->getParent())
- OnlyUsedInOneBlock = false;
+ setOnlyUsedInOneBlock(false);
}
}
SmallVector<DbgVariableRecord *> AllDPUsers;
@@ -426,10 +428,11 @@ struct PromoteMem2Reg {
VectorWithUndo<DebugLoc> IncomingLocs;
// DFS work stack.
- SmallVector<RenamePassData, 8> Worklist;
+ llvm::SmallVectorWithFlags<RenamePassData, 8> Worklist;
/// Whether the function has the no-signed-zeros-fp-math attribute set.
- bool NoSignedZeros = false;
+ bool getNoSignedZeros() const { return Worklist.getFlag(0); }
+ void setNoSignedZeros(bool Value) { Worklist.setFlag(0, Value); }
public:
PromoteMem2Reg(ArrayRef<AllocaInst *> Allocas, DominatorTree &DT,
@@ -808,7 +811,8 @@ void PromoteMem2Reg::run() {
LargeBlockInfo LBI;
ForwardIDFCalculator IDF(DT);
- NoSignedZeros = F.getFnAttribute("no-signed-zeros-fp-math").getValueAsBool();
+ setNoSignedZeros(
+ F.getFnAttribute("no-signed-zeros-fp-math").getValueAsBool());
// removeIntrinsicUsers inserts StoreInst(undef). A cache miss on
// LBI.getInstructionIndex lookup causes a full O(|BB|) basic block rescan.
@@ -852,7 +856,7 @@ void PromoteMem2Reg::run() {
// If the alloca is only read and written in one basic block, just perform a
// linear sweep over the block to eliminate it.
- if (Info.OnlyUsedInOneBlock &&
+ if (Info.getOnlyUsedInOneBlock() &&
promoteSingleBlockAlloca(AI, Info, LBI, SQ.DL, DT, AC,
&DVRAssignsToDelete)) {
// The alloca has been processed, move on.
@@ -1180,7 +1184,7 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
// on the phi node generated at this stage, fabs folding does not
// happen. So, we try to infer nsz flag from the function attributes to
// enable this fabs folding.
- if (isa<FPMathOperator>(APN) && NoSignedZeros)
+ if (isa<FPMathOperator>(APN) && getNoSignedZeros())
APN->setHasNoSignedZeros(true);
// The currently active variable for this block is now the PHI.
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 0bca4213e995b..796c23e8fad46 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -337,7 +337,7 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
bool IsNSW = any(Flags & SCEV::FlagNSW);
// Don't use folder when expanding post-inc rewrites in LSRMode to preserve
// the rewrites.
- if (LSRMode && !PostIncLoops.empty() &&
+ if (getLSRMode() && !PostIncLoops.empty() &&
all_of(PostIncLoops, [&](const Loop *L) {
return !L->contains(Builder.GetInsertBlock());
})) {
@@ -728,7 +728,7 @@ Value *SCEVExpander::visitUDivExpr(SCEVUseT<const SCEVUDivExpr *> S) {
const SCEV *RHSExpr = S->getRHS();
Value *RHS = expand(RHSExpr);
- if (SafeUDivMode) {
+ if (getSafeUDivMode()) {
bool GuaranteedNotPoison =
ScalarEvolution::isGuaranteedNotToBePoison(RHSExpr);
if (!GuaranteedNotPoison)
@@ -1057,7 +1057,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
continue;
// Check whether we can reuse this PHI node.
- if (LSRMode) {
+ if (getLSRMode()) {
if (!isExpandedAddRecExprPHI(&PN, TempIncV, L))
continue;
} else {
@@ -1353,7 +1353,7 @@ Value *SCEVExpander::visitAddRecExpr(SCEVUseT<const SCEVAddRecExpr *> S) {
// proper type might produce non-legal types, for example expanding an i64
// {0,+,2,+,1} addrec would need an i65 canonical IV. To avoid this just fall
// back to non-canonical mode for nested addrecs.
- if (!CanonicalMode || (S->getNumOperands() > 2))
+ if (!getCanonicalMode() || (S->getNumOperands() > 2))
return expandAddRecExprLiterally(S);
Type *Ty = SE.getEffectiveSCEVType(S->getType());
@@ -1535,14 +1535,14 @@ SCEVExpander::visitSignExtendExpr(SCEVUseT<const SCEVSignExtendExpr *> S) {
Value *SCEVExpander::expandMinMaxExpr(SCEVUseT<const SCEVNAryExpr *> S,
Intrinsic::ID IntrinID, Twine Name,
bool IsSequential) {
- bool PrevSafeMode = SafeUDivMode;
- SafeUDivMode |= IsSequential;
+ bool PrevSafeMode = getSafeUDivMode();
+ setSafeUDivMode(getSafeUDivMode() | (IsSequential));
Value *LHS = expand(S->getOperand(S->getNumOperands() - 1));
Type *Ty = LHS->getType();
if (IsSequential)
LHS = Builder.CreateFreeze(LHS);
for (int i = S->getNumOperands() - 2; i >= 0; --i) {
- SafeUDivMode = (IsSequential && i != 0) || PrevSafeMode;
+ setSafeUDivMode((IsSequential && i != 0) || PrevSafeMode);
Value *RHS = expand(S->getOperand(i));
if (IsSequential && i != 0)
RHS = Builder.CreateFreeze(RHS);
@@ -1558,7 +1558,7 @@ Value *SCEVExpander::expandMinMaxExpr(SCEVUseT<const SCEVNAryExpr *> S,
}
LHS = Sel;
}
- SafeUDivMode = PrevSafeMode;
+ setSafeUDivMode(PrevSafeMode);
return LHS;
}
@@ -1611,7 +1611,7 @@ Value *SCEVExpander::FindValueInExprValueMap(
SmallVectorImpl<Instruction *> &DropPoisonGeneratingInsts) {
// If the expansion is not in CanonicalMode, and the SCEV contains any
// sub scAddRecExpr type SCEV, it is required to expand the SCEV literally.
- if (!CanonicalMode && SE.containsAddRecurrence(S))
+ if (!getCanonicalMode() && SE.containsAddRecurrence(S))
return nullptr;
// If S is a constant or unknown, it may be worse to reuse an existing Value.
@@ -2438,7 +2438,7 @@ Value *SCEVExpander::expandUnionPredicate(const SCEVUnionPredicate *Union,
Value *SCEVExpander::fixupLCSSAFormFor(Value *V) {
auto *DefI = dyn_cast<Instruction>(V);
- if (!PreserveLCSSA || !DefI)
+ if (!getPreserveLCSSA() || !DefI)
return V;
BasicBlock::iterator InsertPt = Builder.GetInsertPoint();
@@ -2533,7 +2533,7 @@ struct SCEVFindUnsafe {
} // namespace
bool SCEVExpander::isSafeToExpand(const SCEV *S) const {
- SCEVFindUnsafe Search(SE, CanonicalMode);
+ SCEVFindUnsafe Search(SE, getCanonicalMode());
visitAll(S, Search);
return !Search.IsUnsafe;
}
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index d13d50fbc91ca..aebc99b0b2f7f 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -14,6 +14,7 @@
#include "llvm/Transforms/Utils/SimplifyIndVar.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ValueTracking.h"
@@ -1069,9 +1070,13 @@ class WidenIV {
// 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 getHasGuards() const { return NarrowIVUsers.getFlag(0); }
+ void setHasGuards(bool Value) { NarrowIVUsers.setFlag(0, Value); }
- bool UsePostIncrementRanges;
+ bool getUsePostIncrementRanges() const { return NarrowIVUsers.getFlag(1); }
+ void setUsePostIncrementRanges(bool Value) {
+ NarrowIVUsers.setFlag(1, Value);
+ }
// Statistics
unsigned NumElimExt = 0;
@@ -1179,7 +1184,7 @@ class WidenIV {
void pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef);
private:
- SmallVector<NarrowIVDefUse, 8> NarrowIVUsers;
+ llvm::SmallVectorWithFlags<NarrowIVDefUse, 8, 2> NarrowIVUsers;
};
} // namespace
@@ -1235,14 +1240,15 @@ static Instruction *getInsertPointForUses(Instruction *User, Value *Def,
}
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 ? ExtendKind::Sign : ExtendKind::Zero;
+ 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),
+ DeadInsts(DI),
+ NarrowIVUsers(decltype(this->NarrowIVUsers)::withFlags(
+ unsigned(HasGuards) | (unsigned(UsePostIncrementRanges) << 1))) {
+ assert(L->getHeader() == OrigPhi->getParent() && "Phi must be an IV");
+ ExtendKindMap[OrigPhi] = WI.IsSigned ? ExtendKind::Sign : ExtendKind::Zero;
}
Value *WidenIV::createExtendInst(Value *NarrowOper, Type *WideType,
@@ -2086,7 +2092,7 @@ PHINode *WidenIV::createWideIV(SCEVExpander &Rewriter) {
// 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)
+ if (getUsePostIncrementRanges())
calculatePostIncRanges(OrigPhi);
// The rewriter provides a value for the desired IV expression. This may
@@ -2204,7 +2210,7 @@ void WidenIV::calculatePostIncRange(Instruction *NarrowDef,
};
auto UpdateRangeFromGuards = [&](Instruction *Ctx) {
- if (!HasGuards)
+ if (!getHasGuards())
return;
for (Instruction &I : make_range(Ctx->getIterator().getReverse(),
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 9cfe3f55140b3..89ad2abfba426 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -326,7 +326,7 @@ static bool storeToSameAddress(ScalarEvolution *SE, StoreInst *A,
}
void LoopVectorizationLegality::collectUnitStridePredicates() const {
- if (!AllowRuntimeSCEVChecks || !TheLoop->isInnermost())
+ if (!getAllowRuntimeSCEVChecks() || !TheLoop->isInnermost())
return;
for (BasicBlock *BB : TheLoop->blocks())
@@ -343,12 +343,12 @@ int LoopVectorizationLegality::isConsecutivePtr(Type *AccessTy,
// masked access.
// Stride versioning requires adding a SCEV equality predicate; only consult
// the symbolic strides when runtime SCEV checks are permitted.
- const auto &Strides = LAI && AllowRuntimeSCEVChecks
+ const auto &Strides = LAI && getAllowRuntimeSCEVChecks()
? LAI->getSymbolicStrides()
: SymbolicStrideMap();
SmallVector<const SCEVPredicate *> Predicates;
int Stride = getPtrStride(PSE, AccessTy, Ptr, TheLoop, *DT, Strides, false,
- AllowRuntimeSCEVChecks ? &Predicates : nullptr)
+ getAllowRuntimeSCEVChecks() ? &Predicates : nullptr)
.value_or(0);
if (Stride != 1 && Stride != -1)
return 0;
@@ -947,7 +947,7 @@ bool LoopVectorizationLegality::canVectorizeInstr(Instruction &I) {
// If we found a vectorized variant of a function, note that so LV can
// make better decisions about maximum VF.
if (CI && !VFDatabase::getMappings(*CI).empty())
- VecCallVariantsFound = true;
+ setVecCallVariantsFound(true);
// Check that the instruction return and stored types are vectorizable.
if (!canWidenTypes(I, /*AllowStructCalls=*/true, ORE, TheLoop))
@@ -2011,7 +2011,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
if (Result) {
LLVM_DEBUG(dbgs() << "LV: Loop passed LoopVectorizationLegality checks"
- << (LAI->getRuntimePointerChecking()->Need
+ << (LAI->getRuntimePointerChecking()->needsChecking()
? " (with a runtime bound check)"
: "")
<< "!\n");
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp
index 923fec0283b0c..9f7959573e932 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.cpp
@@ -573,7 +573,7 @@ bool VFSelectionContext::runtimeChecksRequired() {
LLVM_DEBUG(dbgs() << "LV: Performing code size checks.\n");
Loop *L = const_cast<Loop *>(TheLoop);
- if (Legal->getRuntimePointerChecking()->Need) {
+ if (Legal->getRuntimePointerChecking()->needsChecking()) {
reportVectorizationFailure(
"Runtime ptr check is required with -Os/-Oz",
"runtime pointer checks needed. Enable vectorization of this "
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index bf211037d37e5..c954ba192cbd1 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -1338,7 +1338,7 @@ class GeneratedRTChecks {
// TODO: We need to estimate the cost of alias-masking in
// GeneratedRTChecks::getCost(). We can't check the MemCheckBlock as the
// alias-mask is generated later in VPlan.
- if (RtPtrChecking.Need && !LoopUsesPartialAliasMasking) {
+ if (RtPtrChecking.needsChecking() && !LoopUsesPartialAliasMasking) {
auto *Pred = SCEVCheckBlock ? SCEVCheckBlock : Preheader;
MemCheckBlock = SplitBlock(Pred, Pred->getTerminator(), DT, LI, nullptr,
"vector.memcheck");
@@ -2643,7 +2643,8 @@ LoopVectorizationCostModel::computeMaxVF(ElementCount UserVF, unsigned UserIC) {
return Config.computeVPlanOuterloopVF(UserVF);
}
- if (Legal->getRuntimePointerChecking()->Need && TTI.hasBranchDivergence()) {
+ if (Legal->getRuntimePointerChecking()->needsChecking() &&
+ TTI.hasBranchDivergence()) {
// TODO: It may be useful to do since it's still likely to be dynamically
// uniform if the target can skip.
reportVectorizationFailure(
@@ -3640,7 +3641,7 @@ LoopVectorizationPlanner::selectInterleaveCount(VPlan &Plan, ElementCount VF,
return Legal->blockNeedsPredication(BB);
}));
bool ScalarInterleavingRequiresRuntimePointerCheck =
- (VF.isScalar() && Legal->getRuntimePointerChecking()->Need);
+ (VF.isScalar() && Legal->getRuntimePointerChecking()->needsChecking());
// We want to interleave small loops in order to reduce the loop overhead and
// potentially expose ILP opportunities.
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index a1a25390cbfc3..8ee5e6a1cf67d 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -36,6 +36,7 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVectorExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
@@ -289,39 +290,45 @@ class slpvectorizer::BoUpSLP {
/// dependency between two distinct, range-checkable base objects, i.e. a
/// dependency that could be turned into a runtime alias check.
bool hasRuntimeCheckableBlockers() const {
- return HasRuntimeCheckableBlockers;
+ return getHasRuntimeCheckableBlockersFlag();
}
/// Records whether a may-alias dependency between distinct, range-checkable
/// base objects has been observed, so the caller can decide to retry with
/// runtime alias checks enabled.
void setHasRuntimeCheckableBlockers(bool V) {
- HasRuntimeCheckableBlockers = V;
+ setHasRuntimeCheckableBlockersFlag(V);
}
/// Returns true if the last buildTree() kept a may-alias memory dependency
/// that is not runtime-checkable (call or a non-simple mem access). Such a
/// dependency cannot be dropped, so a runtime-checks retry cannot unblock the
/// region and would be pure overhead.
- bool hasNonCheckableMemBlocker() const { return HasNonCheckableMemBlocker; }
+ bool hasNonCheckableMemBlocker() const {
+ return getHasNonCheckableMemBlockerFlag();
+ }
/// Records that a non-runtime-checkable may-alias dependency was kept.
- void setHasNonCheckableMemBlocker(bool V) { HasNonCheckableMemBlocker = V; }
+ void setHasNonCheckableMemBlocker(bool V) {
+ setHasNonCheckableMemBlockerFlag(V);
+ }
/// Returns true if the current vectorization attempt may drop
/// runtime-checkable may-alias dependencies and guard the region with
/// runtime alias checks.
- bool isTryingRuntimeAliasChecks() const { return TryRuntimeAliasChecks; }
+ bool isTryingRuntimeAliasChecks() const {
+ return getTryRuntimeAliasChecksFlag();
+ }
/// Enables or disables dropping runtime-checkable may-alias dependencies in
/// favor of runtime alias checks for the current vectorization attempt.
- void setTryRuntimeAliasChecks(bool V) { TryRuntimeAliasChecks = V; }
+ void setTryRuntimeAliasChecks(bool V) { setTryRuntimeAliasChecksFlag(V); }
/// Resets the runtime alias check data.
void resetRuntimeAliasCheckState() {
- HasRuntimeCheckableBlockers = false;
- HasNonCheckableMemBlocker = false;
- RTChecksFinalized = false;
+ setHasRuntimeCheckableBlockersFlag(false);
+ setHasNonCheckableMemBlockerFlag(false);
+ setRTChecksFinalized(false);
RTChecks.clear();
RTOrigBodyOrder.clear();
}
@@ -369,7 +376,7 @@ class slpvectorizer::BoUpSLP {
/// Returns true if vectorization changed the CFG (i.e. a block was versioned
/// with runtime alias checks). When true, CFG analyses must not be preserved.
- bool isCFGChanged() const { return CFGChanged; }
+ bool isCFGChanged() const { return getCFGChanged(); }
TreeEntry &getRootNode() {
assert(!VectorizableTree.empty() && "No graph to get the first node from");
@@ -475,7 +482,7 @@ class slpvectorizer::BoUpSLP {
EntryToLastInstruction.clear();
LastInstructionToPos.clear();
LoadEntriesToVectorize.clear();
- IsGraphTransformMode = false;
+ setIsGraphTransformMode(false);
GatheredLoadsEntriesFirst.reset();
SplatGatheredScalarsRoots.clear();
NumCanonicalSplatSubtreeEntries = 0;
@@ -485,9 +492,9 @@ class slpvectorizer::BoUpSLP {
ExternalUsesWithNonUsers.clear();
ExternalUseReplacements.clear();
RTChecks.clear();
- HasRuntimeCheckableBlockers = false;
- HasNonCheckableMemBlocker = false;
- RTChecksFinalized = false;
+ setHasRuntimeCheckableBlockersFlag(false);
+ setHasNonCheckableMemBlockerFlag(false);
+ setRTChecksFinalized(false);
for (auto &Iter : BlocksSchedules) {
BlockScheduling *BS = Iter.second.get();
BS->clear();
@@ -3411,7 +3418,8 @@ class slpvectorizer::BoUpSLP {
SetVector<unsigned> LoadEntriesToVectorize;
/// true if graph nodes transforming mode is on.
- bool IsGraphTransformMode = false;
+ bool getIsGraphTransformMode() const { return MergedLoopBTCs.getFlag(0); }
+ void setIsGraphTransformMode(bool Value) { MergedLoopBTCs.setFlag(0, Value); }
/// The index of the first gathered load entry in the VectorizeTree.
std::optional<unsigned> GatheredLoadsEntriesFirst;
@@ -3450,11 +3458,17 @@ class slpvectorizer::BoUpSLP {
/// The loop nest, used to check if only a single loop nest is vectorized, not
/// multiple, to avoid side-effects from the loop-aware cost model.
- SmallVector<const Loop *> CurrentLoopNest;
+ llvm::SmallVectorWithFlags<
+ const Loop *,
+ llvm::CalculateSmallVectorDefaultInlinedElements<const Loop *>::value, 2>
+ CurrentLoopNest;
/// Per-depth SCEVs trip counts at every loop level where the tree builder has
/// joined diverging sibling loops.
- SmallVector<const SCEV *> MergedLoopBTCs;
+ llvm::SmallVectorWithFlags<
+ const SCEV *,
+ llvm::CalculateSmallVectorDefaultInlinedElements<const SCEV *>::value, 4>
+ MergedLoopBTCs;
/// Maps the loops to their loop nests.
SmallDenseMap<const Loop *, SmallVector<const Loop *>> LoopToLoopNest;
@@ -3542,7 +3556,12 @@ class slpvectorizer::BoUpSLP {
/// When true, scheduling drops may-alias memory dependencies between
/// distinct, range-checkable base objects and records them as runtime alias
/// checks instead.
- bool TryRuntimeAliasChecks = false;
+ bool getTryRuntimeAliasChecksFlag() const {
+ return MergedLoopBTCs.getFlag(1);
+ }
+ void setTryRuntimeAliasChecksFlag(bool Value) {
+ MergedLoopBTCs.setFlag(1, Value);
+ }
/// Runtime alias checks collected during the last optimistic buildTree().
RuntimeAliasCheckInfo RTChecks;
@@ -3568,18 +3587,30 @@ class slpvectorizer::BoUpSLP {
/// True, if a may-alias dependency between distinct, range-checkable base
/// objects is observed (whether or not it was dropped).
- bool HasRuntimeCheckableBlockers = false;
+ bool getHasRuntimeCheckableBlockersFlag() const {
+ return MergedLoopBTCs.getFlag(2);
+ }
+ void setHasRuntimeCheckableBlockersFlag(bool Value) {
+ MergedLoopBTCs.setFlag(2, Value);
+ }
/// True, if a kept may-alias dependency is not runtime-checkable (call or a
/// non-simple memaccess).
- bool HasNonCheckableMemBlocker = false;
+ bool getHasNonCheckableMemBlockerFlag() const {
+ return MergedLoopBTCs.getFlag(3);
+ }
+ void setHasNonCheckableMemBlockerFlag(bool Value) {
+ MergedLoopBTCs.setFlag(3, Value);
+ }
/// Runtime checks are validated and bounded the collected checks.
- bool RTChecksFinalized = false;
+ bool getRTChecksFinalized() const { return CurrentLoopNest.getFlag(0); }
+ void setRTChecksFinalized(bool Value) { CurrentLoopNest.setFlag(0, Value); }
/// Set when a block was versioned with runtime alias checks, which changes
/// the CFG. Used to drop CFG-analysis preservation for the run.
- bool CFGChanged = false;
+ bool getCFGChanged() const { return CurrentLoopNest.getFlag(1); }
+ void setCFGChanged(bool Value) { CurrentLoopNest.setFlag(1, Value); }
/// Guarded block body (non-PHI, non-alloca, non-terminator) in original
/// source order.
@@ -3929,13 +3960,15 @@ class slpvectorizer::BoUpSLP {
class ScheduleBundle final : public ScheduleEntity {
/// The schedule data for the instructions in the bundle.
- SmallVector<ScheduleEntity *> Bundle;
+ llvm::SmallVectorWithFlags<ScheduleEntity *> Bundle;
/// True if this bundle is valid.
- bool IsValid = true;
+ bool getIsValid() const { return !Bundle.getFlag(0); }
+ void setIsValid(bool Value) { Bundle.setFlag(0, !Value); }
/// The TreeEntry that this instruction corresponds to.
TreeEntry *TE = nullptr;
ScheduleBundle(bool IsValid)
- : ScheduleEntity(Kind::ScheduleBundle), IsValid(IsValid) {}
+ : ScheduleEntity(Kind::ScheduleBundle),
+ Bundle(decltype(this->Bundle)::withFlags(unsigned(!(IsValid)))) {}
public:
ScheduleBundle() : ScheduleEntity(Kind::ScheduleBundle) {}
@@ -4002,7 +4035,7 @@ class slpvectorizer::BoUpSLP {
static ScheduleBundle invalid() { return {false}; }
- operator bool() const { return IsValid; }
+ operator bool() const { return getIsValid(); }
#ifndef NDEBUG
void dump(raw_ostream &OS) const {
@@ -4182,8 +4215,8 @@ class slpvectorizer::BoUpSLP {
ScheduleEnd = nullptr;
FirstLoadStoreInRegion = nullptr;
LastLoadStoreInRegion = nullptr;
- RegionHasStackSave = false;
- RegionHasMayThrow = false;
+ setRegionHasStackSave(false);
+ setRegionHasMayThrow(false);
// Reduce the maximum schedule region size by the size of the
// previous scheduling run.
@@ -5241,7 +5274,11 @@ class slpvectorizer::BoUpSLP {
SmallDenseMap<Instruction *, SmallVector<ScheduleBundle *>>
ScheduledBundles;
/// The list of ScheduleBundles.
- SmallVector<std::unique_ptr<ScheduleBundle>> ScheduledBundlesList;
+ llvm::SmallVectorWithFlags<std::unique_ptr<ScheduleBundle>,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ std::unique_ptr<ScheduleBundle>>::value,
+ 2>
+ ScheduledBundlesList;
/// The ready-list for scheduling (only used for the dry-run).
SetVector<ScheduleEntity *> ReadyInsts;
@@ -5263,16 +5300,28 @@ class slpvectorizer::BoUpSLP {
/// Is there an llvm.stacksave or llvm.stackrestore in the scheduling
/// region? Used to optimize the dependence calculation for the
/// common case where there isn't.
- bool RegionHasStackSave = false;
+ bool getRegionHasStackSave() const {
+ return ScheduledBundlesList.getFlag(0);
+ }
+ bool setRegionHasStackSave(bool Value) {
+ ScheduledBundlesList.setFlag(0, Value);
+ return Value;
+ }
/// Used to skip the dependencies calculation for writes that are visible
/// after unwinding.
- bool RegionHasMayThrow = false;
+ bool getRegionHasMayThrow() const {
+ return ScheduledBundlesList.getFlag(1);
+ }
+ bool setRegionHasMayThrow(bool Value) {
+ ScheduledBundlesList.setFlag(1, Value);
+ return Value;
+ }
/// Returns true if \p I writes memory that the caller can still see
/// after an unwind.
bool isWriteVisibleOnUnwind(Instruction *I) const {
- if (!RegionHasMayThrow || !I->mayWriteToMemory())
+ if (!getRegionHasMayThrow() || !I->mayWriteToMemory())
return false;
MemoryLocation Loc = getLocation(I);
if (!Loc.Ptr)
@@ -9466,7 +9515,7 @@ BoUpSLP::TreeEntry::EntryState BoUpSLP::getScalarsVectorizationState(
case LoadsState::Vectorize:
return TreeEntry::Vectorize;
case LoadsState::CompressVectorize:
- if (!IsGraphTransformMode && VectorizableTree.size() > 1) {
+ if (!getIsGraphTransformMode() && VectorizableTree.size() > 1) {
// Delay slow vectorized nodes for better vectorization attempts.
LoadEntriesToVectorize.insert(VectorizableTree.size());
return TreeEntry::NeedToGather;
@@ -9474,7 +9523,7 @@ BoUpSLP::TreeEntry::EntryState BoUpSLP::getScalarsVectorizationState(
return IsGatheredNode() ? TreeEntry::NeedToGather
: TreeEntry::CompressVectorize;
case LoadsState::ScatterVectorize:
- if (!IsGraphTransformMode && VectorizableTree.size() > 1) {
+ if (!getIsGraphTransformMode() && VectorizableTree.size() > 1) {
// Delay slow vectorized nodes for better vectorization attempts.
LoadEntriesToVectorize.insert(VectorizableTree.size());
return TreeEntry::NeedToGather;
@@ -9482,7 +9531,7 @@ BoUpSLP::TreeEntry::EntryState BoUpSLP::getScalarsVectorizationState(
return IsGatheredNode() ? TreeEntry::NeedToGather
: TreeEntry::ScatterVectorize;
case LoadsState::StridedVectorize:
- if (!IsGraphTransformMode && VectorizableTree.size() > 1) {
+ if (!getIsGraphTransformMode() && VectorizableTree.size() > 1) {
// Delay slow vectorized nodes for better vectorization attempts.
LoadEntriesToVectorize.insert(VectorizableTree.size());
return TreeEntry::NeedToGather;
@@ -9490,7 +9539,7 @@ BoUpSLP::TreeEntry::EntryState BoUpSLP::getScalarsVectorizationState(
return IsGatheredNode() ? TreeEntry::NeedToGather
: TreeEntry::StridedVectorize;
case LoadsState::BlendedLoadVectorize:
- if (!IsGraphTransformMode && VectorizableTree.size() > 1) {
+ if (!getIsGraphTransformMode() && VectorizableTree.size() > 1) {
// Delay slow vectorized nodes for better vectorization attempts.
LoadEntriesToVectorize.insert(VectorizableTree.size());
return TreeEntry::NeedToGather;
@@ -11984,8 +12033,12 @@ static void scanAssociativeOperands(
};
// Signs ride with the columns so the parallel lists cannot drift apart.
struct SignedColumn {
- BoUpSLP::ValueList Col;
- bool Negated;
+ SignedColumn(BoUpSLP::ValueList Col, bool Negated)
+ : Col(unsigned(Negated), std::move(Col)) {}
+
+ llvm::SmallVectorWithFlagsFor<BoUpSLP::ValueList, 1> Col;
+ bool getNegated() const { return Col.getFlag(0); }
+ void setNegated(bool Value) { Col.setFlag(0, Value); }
};
SmallVector<SignedColumn, 4> Columns = {
{std::move(Operands[0]), false},
@@ -12029,7 +12082,7 @@ static void scanAssociativeOperands(
++Idx;
continue;
}
- BoUpSLP::ValueList Column = std::move(Columns[Idx].Col);
+ BoUpSLP::ValueList Column = BoUpSLP::ValueList(std::move(Columns[Idx].Col));
// The absorbing constants of the peeled lanes keep the identity as the
// other operand: the poison operand is not frozen in the flattened node.
SmallVector<BoUpSLP::ValueList> SubOperands = Analysis.buildOperands(
@@ -12042,17 +12095,18 @@ static void scanAssociativeOperands(
if (!isa<PoisonValue>(V) && !ColS.isCopyableElement(V))
ReassocScalars.push_back(V);
// A peeled subtract negates its second operand column.
- const bool Negated = Columns[Idx].Negated;
- Columns[Idx].Col = std::move(SubOperands.front());
+ const bool Negated = Columns[Idx].getNegated();
+ Columns[Idx].Col.assign(std::move(SubOperands.front()));
Columns.insert(
std::next(Columns.begin(), Idx + 1),
{std::move(SubOperands.back()), IsSub(ColS.getOpcode()) != Negated});
// Do not advance Idx: re-examine the column that was just placed here.
}
Operands.clear();
- for (auto &[Col, Negated] : Columns) {
- Operands.push_back(std::move(Col));
- NegatedColumns.push_back(Negated);
+ for (auto &Column : Columns) {
+ Operands.push_back(
+ llvm::SmallVector<llvm::Value *, 8>(std::move(Column.Col)));
+ NegatedColumns.push_back(Column.getNegated());
}
}
@@ -12384,7 +12438,7 @@ void BoUpSLP::buildTreeRec(ArrayRef<Value *> VLRef, unsigned Depth,
BailOutToGather();
return;
}
- CurrentLoopNest.assign(NewLoopNest);
+ CurrentLoopNest.assign(NewLoopNest.begin(), NewLoopNest.end());
} else if (CommonLen < CurrentLoopNest.size() &&
CommonLen < NewLoopNest.size()) {
// Divergence below the common prefix: the tree now spans sibling
@@ -14401,15 +14455,14 @@ void BoUpSLP::transformNodes() {
BaseGraphSize = VectorizableTree.size();
// Turn graph transforming mode on and off, when done.
class GraphTransformModeRAAI {
- bool &SavedIsGraphTransformMode;
+ BoUpSLP &R;
public:
- GraphTransformModeRAAI(bool &IsGraphTransformMode)
- : SavedIsGraphTransformMode(IsGraphTransformMode) {
- IsGraphTransformMode = true;
+ GraphTransformModeRAAI(BoUpSLP &R) : R(R) {
+ R.setIsGraphTransformMode(true);
}
- ~GraphTransformModeRAAI() { SavedIsGraphTransformMode = false; }
- } TransformContext(IsGraphTransformMode);
+ ~GraphTransformModeRAAI() { R.setIsGraphTransformMode(false); }
+ } TransformContext(*this);
// Operands are profitable if they are:
// 1. At least one constant
// or
@@ -15085,7 +15138,8 @@ void BoUpSLP::transformNodes() {
/// end of the process, to reduce the number of emitted instructions and further
/// analysis/transformations.
class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
- bool IsFinalized = false;
+ bool getIsFinalized() const { return InVectors.getFlag(0); }
+ void setIsFinalized(bool Value) { InVectors.setFlag(0, Value); }
SmallVector<int> CommonMask;
// Each input vector can be tagged with extra context information
@@ -15102,7 +15156,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
TargetTransformInfo::VectorInstrContext::None)
: Vec(Vec), Ctx(Ctx) {}
};
- SmallVector<InVector, 2> InVectors;
+ llvm::SmallVectorWithFlags<InVector, 2, 2> InVectors;
/// Captures the original scalar VL of a single, "clean" gather() call so
/// the values can be forwarded as the Args operand to getShuffleCost() for
/// the final permutation in finalize(). This lets the target cost model
@@ -15126,7 +15180,8 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
/// can delay actual cost estimation (virtual shuffle instruction emission).
/// May help better estimate the cost if same nodes must be permuted + allows
/// to move most of the long shuffles cost estimation to TTI.
- bool SameNodesEstimated = true;
+ bool getSameNodesEstimated() const { return !InVectors.getFlag(1); }
+ void setSameNodesEstimated(bool Value) { InVectors.setFlag(1, !Value); }
static Constant *getAllOnesValue(const DataLayout &DL, Type *Ty) {
if (Ty->getScalarType()->isPointerTy()) {
@@ -15329,7 +15384,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
void estimateNodesPermuteCost(const TreeEntry &E1, const TreeEntry *E2,
ArrayRef<int> Mask, unsigned Part,
unsigned SliceSize) {
- if (SameNodesEstimated) {
+ if (getSameNodesEstimated()) {
// Delay the cost estimation if the same nodes are reshuffling.
// If we already requested the cost of reshuffling of E1 and E2 before, no
// need to estimate another cost with the sub-Mask, instead include this
@@ -15363,7 +15418,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
{}, InVectors.front().Ctx, InVectors.back().Ctx);
transformMaskAfterShuffle(CommonMask, CommonMask);
}
- SameNodesEstimated = false;
+ setSameNodesEstimated(false);
if (!E2 && InVectors.size() == 1) {
unsigned VF = E1.getVectorFactor();
if (Value *V1 = InVectors.front().Vec.dyn_cast<Value *>()) {
@@ -15789,7 +15844,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
InVectors.assign(1, E);
CommonMask.assign(Mask.begin(), Mask.end());
transformMaskAfterShuffle(CommonMask, CommonMask);
- SameNodesEstimated = false;
+ setSameNodesEstimated(false);
if (NumParts != 1 && UniqueBases.size() != 1) {
UseVecBaseAsInput = true;
VecBase =
@@ -15807,12 +15862,12 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
}
/// Reset the builder to handle perfect diamond match.
void resetForSameNode() {
- IsFinalized = false;
+ setIsFinalized(false);
CommonMask.clear();
InVectors.clear();
Cost = 0;
VectorizedVals.clear();
- SameNodesEstimated = true;
+ setSameNodesEstimated(true);
}
void add(const TreeEntry &E1, const TreeEntry &E2, ArrayRef<int> Mask) {
BVValues.reset();
@@ -15852,7 +15907,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
const auto *It = find_if(Mask, not_equal_to(PoisonMaskElem));
unsigned Part = std::distance(Mask.begin(), It) / SliceSize;
estimateNodesPermuteCost(E1, nullptr, Mask, Part, SliceSize);
- if (!SameNodesEstimated && InVectors.size() == 1)
+ if (!getSameNodesEstimated() && InVectors.size() == 1)
InVectors.emplace_back(&E1);
}
/// Adds 2 input vectors and the mask for their shuffling.
@@ -16023,7 +16078,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
function_ref<void(Value *&, SmallVectorImpl<int> &,
function_ref<Value *(Value *, Value *, ArrayRef<int>)>)>
Action = {}) {
- IsFinalized = true;
+ setIsFinalized(true);
if (Action) {
const PointerUnion<Value *, const TreeEntry *> &Vec =
InVectors.front().Vec;
@@ -16131,7 +16186,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
}
~ShuffleCostEstimator() {
- assert((IsFinalized || CommonMask.empty()) &&
+ assert((getIsFinalized() || CommonMask.empty()) &&
"Shuffle construction must be finalized.");
}
};
@@ -22552,7 +22607,8 @@ Value *BoUpSLP::gather(
/// \endcode
/// instead.
class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
- bool IsFinalized = false;
+ bool getIsFinalized() const { return InVectors.getFlag(0); }
+ void setIsFinalized(bool Value) { InVectors.setFlag(0, Value); }
/// Combined mask for all applied operands and masks. It is built during
/// analysis and actual emission of shuffle vector instructions.
SmallVector<int> CommonMask;
@@ -22561,7 +22617,7 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
/// shuffle with \p CommonMask mask, the first operand sets to be the
/// resulting shuffle and the second operand sets to be the newly added
/// operand. The \p CommonMask is transformed in the proper way after that.
- SmallVector<Value *, 2> InVectors;
+ llvm::SmallVectorWithFlags<Value *, 2> InVectors;
IRBuilderBase &Builder;
BoUpSLP &R;
@@ -22856,7 +22912,7 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
}
/// Reset the builder to handle perfect diamond match.
void resetForSameNode() {
- IsFinalized = false;
+ setIsFinalized(false);
CommonMask.clear();
InVectors.clear();
}
@@ -23014,7 +23070,7 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
function_ref<void(Value *&, SmallVectorImpl<int> &,
function_ref<Value *(Value *, Value *, ArrayRef<int>)>)>
Action = {}) {
- IsFinalized = true;
+ setIsFinalized(true);
if (Action) {
Value *Vec = InVectors.front();
if (InVectors.size() == 2) {
@@ -23113,7 +23169,7 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
}
~ShuffleInstructionBuilder() {
- assert((IsFinalized || CommonMask.empty()) &&
+ assert((getIsFinalized() || CommonMask.empty()) &&
"Shuffle construction must be finalized.");
}
};
@@ -25708,7 +25764,7 @@ static bool blockBodyHasVectorInstructions(const VectorizeOptions &Opts,
void BoUpSLP::captureRuntimeCheckBodySnapshot() {
RTOrigBodyOrder.clear();
- if (!TryRuntimeAliasChecks || !RTChecks.BB)
+ if (!getTryRuntimeAliasChecksFlag() || !RTChecks.BB)
return;
BasicBlock *BB = RTChecks.BB;
// Allocas are not duplicated, keep them in the header block.
@@ -25739,7 +25795,7 @@ bool BoUpSLP::recordRuntimeAliasCheck(BasicBlock *BB, Instruction *Inst1,
RTChecks.BasePairs.contains({Base2, Base1});
// After the checks have been validated and bounded, do not introduce new
// pairs.
- if (RTChecksFinalized)
+ if (getRTChecksFinalized())
return Present;
RTChecks.BB = BB;
if (!Present)
@@ -25938,7 +25994,7 @@ bool BoUpSLP::canVersionForRuntimeChecks() {
// Freeze the check set so the final scheduleBlock() keeps the same dropped
// dependencies the bounds were just computed for.
- RTChecksFinalized = true;
+ setRTChecksFinalized(true);
return true;
}
@@ -26002,8 +26058,8 @@ Value *BoUpSLP::emitRuntimeAliasCheck(IRBuilderBase &Builder,
void BoUpSLP::versionBlocksForRuntimeChecks() {
// Only version when this is the optimistic attempt that collected the checks.
- if (!TryRuntimeAliasChecks || RTChecks.BasePairs.empty() || !RTChecks.BB ||
- RTOrigBodyOrder.empty())
+ if (!getTryRuntimeAliasChecksFlag() || RTChecks.BasePairs.empty() ||
+ !RTChecks.BB || RTOrigBodyOrder.empty())
return;
BasicBlock *BB = RTChecks.BB;
Function *Fn = BB->getParent();
@@ -26131,10 +26187,10 @@ void BoUpSLP::versionBlocksForRuntimeChecks() {
// The checks have been emitted; clear so any later vectorizeTree() in the
// same attempt does not version again.
RTChecks.clear();
- RTChecksFinalized = false;
+ setRTChecksFinalized(false);
RTOrigBodyOrder.clear();
// The CFG was modified; CFG analyses can no longer be preserved.
- CFGChanged = true;
+ setCFGChanged(true);
}
Value *BoUpSLP::vectorizeTree() {
@@ -27510,7 +27566,7 @@ BoUpSLP::BlockScheduling::tryScheduleBundle(ArrayRef<Value *> VL, BoUpSLP *SLP,
if (ScheduleData *BundleMember = getScheduleData(SD->getInst());
BundleMember && BundleMember->hasValidDependencies()) {
BundleMember->clearDirectDependencies();
- if (RegionHasStackSave ||
+ if (getRegionHasStackSave() ||
!isGuaranteedToTransferExecutionToSuccessor(
BundleMember->getInst()) ||
isWriteVisibleOnUnwind(BundleMember->getInst()))
@@ -27540,7 +27596,7 @@ BoUpSLP::BlockScheduling::tryScheduleBundle(ArrayRef<Value *> VL, BoUpSLP *SLP,
if (ScheduleData *OpSD = getScheduleData(Op);
OpSD && OpSD->hasValidDependencies()) {
OpSD->clearDirectDependencies();
- if (RegionHasStackSave ||
+ if (getRegionHasStackSave() ||
!isGuaranteedToTransferExecutionToSuccessor(
OpSD->getInst()) ||
isWriteVisibleOnUnwind(OpSD->getInst()))
@@ -27879,9 +27935,9 @@ void BoUpSLP::BlockScheduling::initScheduleData(Instruction *FromI,
if (match(I, m_Intrinsic<Intrinsic::stacksave>()) ||
match(I, m_Intrinsic<Intrinsic::stackrestore>()))
- RegionHasStackSave = true;
+ setRegionHasStackSave(true);
if (I->mayThrow())
- RegionHasMayThrow = true;
+ setRegionHasMayThrow(true);
}
if (NextLoadStore) {
if (CurrentLoadStore)
@@ -28062,7 +28118,7 @@ void BoUpSLP::BlockScheduling::calculateDependencies(
}
}
- if (RegionHasStackSave) {
+ if (getRegionHasStackSave()) {
// If we have an inalloc alloca instruction, it needs to be scheduled
// after any preceeding stacksave. We also need to prevent any alloca
// from reordering above a preceeding stackrestore.
@@ -30970,12 +31026,17 @@ class HorizontalReduction {
RecurKind RdxKind;
/// Checks if the optimization of original scalar identity operations on
/// matched horizontal reductions is enabled and allowed.
- bool IsSupportedHorRdxIdentityOp = false;
+ bool getIsSupportedHorRdxIdentityOp() const {
+ return VectorValuesAndScales.getFlag(0);
+ }
+ void setIsSupportedHorRdxIdentityOp(bool Value) {
+ VectorValuesAndScales.setFlag(0, Value);
+ }
/// The minimum number of the reduced values.
const unsigned ReductionLimit = Opts.slp_vectorize_non_power_of_2 ? 3 : 4;
/// Contains vector values for reduction including their scale factor,
/// signedness and sign of their contribution to the reduction result.
- SmallVector<ReductionVectorPart> VectorValuesAndScales;
+ llvm::SmallVectorWithFlags<ReductionVectorPart> VectorValuesAndScales;
/// Narrow reduced values mapped to the shift and the mask applied after
/// widening.
@@ -32997,13 +33058,13 @@ class HorizontalReduction {
// Check if we support repeated scalar values processing (optimization of
// original scalar identity operations on matched horizontal reductions).
- IsSupportedHorRdxIdentityOp =
+ setIsSupportedHorRdxIdentityOp(
RK == ReductionOrdering::Unordered && RdxKind != RecurKind::Mul &&
RdxKind != RecurKind::FMul && RdxKind != RecurKind::FMulAdd &&
- (!Opts.slp_revec || !Candidates.front()->getType()->isVectorTy());
+ (!Opts.slp_revec || !Candidates.front()->getType()->isVectorTy()));
// Gather same values.
SmallMapVector<Value *, unsigned, 16> SameValuesCounter;
- if (IsSupportedHorRdxIdentityOp)
+ if (getIsSupportedHorRdxIdentityOp())
for (const auto [Idx, V] : enumerate(Candidates)) {
Value *OrigV = TrackedToOrig[Idx];
++SameValuesCounter.try_emplace(OrigV).first->second;
@@ -33019,7 +33080,7 @@ class HorizontalReduction {
// this analysis, other operations may require an extra estimation of
// the profitability.
bool SameScaleFactor = false;
- bool OptReusedScalars = IsSupportedHorRdxIdentityOp &&
+ bool OptReusedScalars = getIsSupportedHorRdxIdentityOp() &&
SameValuesCounter.size() != Candidates.size();
BoUpSLP::ExtraValueToDebugLocsMap ExternallyUsedValues;
for (Value *RdxVal : ExcludedVectorizedReducedVals)
@@ -33201,7 +33262,7 @@ class HorizontalReduction {
make_isa_range<Instruction>(ReducedVals[Cnt]))
LocalExternallyUsedValues.insert(TrackedVals[Inst]);
}
- if (!IsSupportedHorRdxIdentityOp) {
+ if (!getIsSupportedHorRdxIdentityOp()) {
// Number of uses of the candidates in the vector of values.
assert(SameValuesCounter.empty() &&
"Reused values counter map is not empty");
@@ -33220,7 +33281,7 @@ class HorizontalReduction {
const bool LoopAccCandidate =
!GroupNegated &&
LoopAcc.isCandidate(VectorizedTree, !VectorValuesAndScales.empty(),
- IsSupportedHorRdxIdentityOp, ReducedVals,
+ getIsSupportedHorRdxIdentityOp(), ReducedVals,
Candidates, I, Pos, ReduxWidth,
OptReusedScalars, SameScaleFactor);
@@ -33248,7 +33309,7 @@ class HorizontalReduction {
LocalExternallyUsedValues.insert(RdxVal);
}
// Do not need the list of reused scalars in regular mode anymore.
- if (!IsSupportedHorRdxIdentityOp)
+ if (!getIsSupportedHorRdxIdentityOp())
SameValuesCounter.clear();
for (Value *RdxVal : VL)
if (RequiredExtract.contains(RdxVal))
@@ -33460,7 +33521,7 @@ class HorizontalReduction {
// Count vectorized reduced values to exclude them from final reduction.
for (const auto [Idx, RdxVal] : enumerate(VL)) {
Value *OrigV = TrackedToOrig[Pos + Idx];
- if (IsSupportedHorRdxIdentityOp) {
+ if (getIsSupportedHorRdxIdentityOp()) {
VectorizedVals.try_emplace(OrigV, At(SameValuesCounter, OrigV));
continue;
}
@@ -34833,7 +34894,7 @@ class HorizontalReduction {
/// Emits optimized code for unique scalar value reused \p Cnt times.
Value *emitScaleForReusedOps(Value *VectorizedValue, IRBuilderBase &Builder,
unsigned Cnt) {
- assert(IsSupportedHorRdxIdentityOp &&
+ assert(getIsSupportedHorRdxIdentityOp() &&
"The optimization of matched scalar identity horizontal reductions "
"must be supported.");
if (Cnt == 1)
@@ -34909,7 +34970,7 @@ class HorizontalReduction {
emitReusedOps(Value *VectorizedValue, IRBuilderBase &Builder, BoUpSLP &R,
const SmallMapVector<Value *, unsigned, 16> &SameValuesCounter,
ArrayRef<Value *> TrackedToOrig) {
- assert(IsSupportedHorRdxIdentityOp &&
+ assert(getIsSupportedHorRdxIdentityOp() &&
"The optimization of matched scalar identity horizontal reductions "
"must be supported.");
ArrayRef<Value *> VL = R.getRootNodeScalars();
diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp
index 526ed936cbfd0..57cddaa3a8dcb 100644
--- a/llvm/tools/dsymutil/MachODebugMapParser.cpp
+++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp
@@ -13,6 +13,7 @@
#include "dsymutil.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/Chrono.h"
@@ -39,8 +40,8 @@ class MachODebugMapParser {
: BinaryPath(std::string(BinaryPath)), Archs(Archs),
DSYMSearchPaths(DSYMSearchPaths), PathPrefix(std::string(PathPrefix)),
VariantSuffix(std::string(VariantSuffix)), BinHolder(BinHolder),
- CurrentDebugMapObject(nullptr), SkipDebugMapObject(false),
- ObjectFilter(ObjectFilter), ObjectFilterType(ObjectFilterType) {}
+ CurrentDebugMapObject(nullptr), ObjectFilter(ObjectFilter),
+ ObjectFilterType(ObjectFilterType) {}
/// Parses and returns the DebugMaps of the input binary. The binary contains
/// multiple maps in case it is a universal binary.
@@ -56,7 +57,7 @@ class MachODebugMapParser {
private:
std::string BinaryPath;
SmallVector<StringRef, 1> Archs;
- SmallVector<StringRef, 1> DSYMSearchPaths;
+ llvm::SmallVectorWithFlags<StringRef, 1> DSYMSearchPaths;
std::string PathPrefix;
std::string VariantSuffix;
@@ -83,7 +84,8 @@ class MachODebugMapParser {
DebugMapObject *CurrentDebugMapObject;
/// Whether we need to skip the current debug map object.
- bool SkipDebugMapObject;
+ bool getSkipDebugMapObject() const { return DSYMSearchPaths.getFlag(0); }
+ void setSkipDebugMapObject(bool Value) { DSYMSearchPaths.setFlag(0, Value); }
/// Optional set of object paths to filter on.
const std::optional<StringSet<>> &ObjectFilter;
@@ -177,7 +179,7 @@ void MachODebugMapParser::resetParserState() {
CurrentObjectAliasMap.clear();
SeenAliasValues.clear();
CurrentDebugMapObject = nullptr;
- SkipDebugMapObject = false;
+ setSkipDebugMapObject(false);
}
/// Commons symbols won't show up in the symbol map but might need to be
@@ -212,7 +214,7 @@ void MachODebugMapParser::switchToNewDebugMapObject(
sys::path::append(Path, Filename);
if (!shouldIncludeObject(Path)) {
- SkipDebugMapObject = true;
+ setSkipDebugMapObject(true);
return;
}
@@ -664,7 +666,7 @@ void MachODebugMapParser::handleStabSymbolTableEntry(
if (!CurrentDebugMapObject ||
CurrentDebugMapObject->getType() != MachO::N_LIB) {
if (Duplicates.count(OSO(Name, Value))) {
- SkipDebugMapObject = true;
+ setSkipDebugMapObject(true);
return;
}
switchToNewDebugMapObject(Name, sys::toTimePoint(Value));
@@ -672,7 +674,7 @@ void MachODebugMapParser::handleStabSymbolTableEntry(
return;
}
- if (SkipDebugMapObject)
+ if (getSkipDebugMapObject())
return;
if (Type == MachO::N_AST) {
diff --git a/llvm/tools/dsymutil/Reproducer.cpp b/llvm/tools/dsymutil/Reproducer.cpp
index 0c1d3f90af299..ed79d433c9fef 100644
--- a/llvm/tools/dsymutil/Reproducer.cpp
+++ b/llvm/tools/dsymutil/Reproducer.cpp
@@ -35,7 +35,8 @@ Reproducer::~Reproducer() = default;
ReproducerGenerate::ReproducerGenerate(std::error_code &EC, int Argc,
char **Argv, bool GenerateOnExit)
- : Root(createReproducerDir(EC)), GenerateOnExit(GenerateOnExit) {
+ : Root(createReproducerDir(EC)),
+ Args(decltype(Args)::withFlags(unsigned(GenerateOnExit))) {
llvm::append_range(Args, ArrayRef(Argv, Argc));
auto RealFS = vfs::getRealFileSystem();
if (!Root.empty())
@@ -44,16 +45,16 @@ ReproducerGenerate::ReproducerGenerate(std::error_code &EC, int Argc,
}
ReproducerGenerate::~ReproducerGenerate() {
- if (GenerateOnExit && !Generated)
+ if (getGenerateOnExit() && !getGenerated())
generate();
- else if (!Generated && !Root.empty())
+ else if (!getGenerated() && !Root.empty())
sys::fs::remove_directories(Root, /* IgnoreErrors */ true);
}
void ReproducerGenerate::generate() {
if (!FC)
return;
- Generated = true;
+ setGenerated(true);
FC->copyFiles(false);
SmallString<128> Mapping(Root);
sys::path::append(Mapping, "mapping.yaml");
diff --git a/llvm/tools/dsymutil/Reproducer.h b/llvm/tools/dsymutil/Reproducer.h
index b53b485fbea6c..f681b1e146cd7 100644
--- a/llvm/tools/dsymutil/Reproducer.h
+++ b/llvm/tools/dsymutil/Reproducer.h
@@ -9,6 +9,7 @@
#ifndef LLVM_TOOLS_DSYMUTIL_REPRODUCER_H
#define LLVM_TOOLS_DSYMUTIL_REPRODUCER_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/FileCollector.h"
#include "llvm/Support/VirtualFileSystem.h"
@@ -63,13 +64,15 @@ class ReproducerGenerate : public Reproducer {
std::shared_ptr<FileCollector> FC;
/// The input arguments to build the reproducer invocation.
- llvm::SmallVector<llvm::StringRef, 0> Args;
+ llvm::SmallVectorWithFlags<llvm::StringRef, 0, 2> Args;
/// Whether to generate the reproducer on destruction.
- bool GenerateOnExit = false;
+ bool getGenerateOnExit() const { return Args.getFlag(0); }
+ void setGenerateOnExit(bool Value) { Args.setFlag(0, Value); }
/// Whether we already generated the reproducer.
- bool Generated = false;
+ bool getGenerated() const { return Args.getFlag(1); }
+ void setGenerated(bool Value) { Args.setFlag(1, Value); }
};
/// Reproducer instance used to use an existing reproducer. The VFS returned by
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h
index bde187ea35ed1..d4e5aa08328d6 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.h
+++ b/llvm/tools/llvm-cov/SourceCoverageView.h
@@ -13,8 +13,9 @@
#ifndef LLVM_COV_SOURCECOVERAGEVIEW_H
#define LLVM_COV_SOURCECOVERAGEVIEW_H
-#include "CoverageViewOptions.h"
#include "CoverageSummaryInfo.h"
+#include "CoverageViewOptions.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
#include "llvm/Support/MemoryBuffer.h"
#include <vector>
@@ -167,13 +168,14 @@ class SourceCoverageView {
SmallVector<BranchView, 0> BranchSubViews;
/// A container for all MCDC records in the source on display.
- SmallVector<MCDCView, 0> MCDCSubViews;
+ llvm::SmallVectorWithFlags<MCDCView, 0> MCDCSubViews;
/// A container for all instantiations (e.g template functions) in the source
/// on display.
std::vector<InstantiationView> InstantiationSubViews;
- bool BinaryCounters;
+ bool getBinaryCounters() const { return MCDCSubViews.getFlag(0); }
+ void setBinaryCounters(bool Value) { MCDCSubViews.setFlag(0, Value); }
/// Get the first uncovered line number for the source file.
unsigned getFirstUncoveredLineNo();
@@ -262,7 +264,7 @@ class SourceCoverageView {
static std::string formatCount(uint64_t N);
uint64_t BinaryCount(uint64_t N) const {
- return (N && BinaryCounters ? 1 : N);
+ return (N && getBinaryCounters() ? 1 : N);
}
std::string formatBinaryCount(uint64_t N) const {
@@ -280,8 +282,9 @@ class SourceCoverageView {
CoverageData &&CoverageInfo)
: SourceName(SourceName), File(File), Options(Options),
CoverageInfo(std::move(CoverageInfo)),
- BinaryCounters(Options.BinaryCounters ||
- CoverageInfo.getSingleByteCoverage()) {}
+ MCDCSubViews(decltype(this->MCDCSubViews)::withFlags(unsigned(bool(
+ Options.BinaryCounters || CoverageInfo.getSingleByteCoverage())))) {
+ }
public:
static std::unique_ptr<SourceCoverageView>
diff --git a/llvm/tools/llvm-dwarfdump/Coverage.cpp b/llvm/tools/llvm-dwarfdump/Coverage.cpp
index 295f3ce3785b4..db9bdc3a4a6b0 100644
--- a/llvm/tools/llvm-dwarfdump/Coverage.cpp
+++ b/llvm/tools/llvm-dwarfdump/Coverage.cpp
@@ -8,6 +8,7 @@
#include "llvm-dwarfdump.h"
#include "llvm/ADT/SetOperations.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
@@ -432,13 +433,22 @@ struct VarKey {
};
struct VarCoverage {
- SmallVector<DWARFDie> Parents;
+ VarCoverage(ArrayRef<DWARFDie> Parents, size_t Cov, size_t BaselineCov,
+ size_t LTCov, size_t Missing, size_t Instances,
+ bool MissingBaseline)
+ : Parents(decltype(this->Parents)::withFlags(unsigned(MissingBaseline),
+ Parents)),
+ Cov(Cov), BaselineCov(BaselineCov), LTCov(LTCov), Missing(Missing),
+ Instances(Instances) {}
+
+ llvm::SmallVectorWithFlags<DWARFDie> Parents;
size_t Cov;
size_t BaselineCov;
size_t LTCov;
size_t Missing;
size_t Instances;
- bool MissingBaseline;
+ bool getMissingBaseline() const { return Parents.getFlag(0); }
+ void setMissingBaseline(bool Value) { Parents.setFlag(0, Value); }
};
typedef std::multimap<VarKey, VarCoverage, std::less<>> VarMap;
@@ -457,7 +467,7 @@ static std::optional<const VarKey> getVarKey(DWARFDie VariableDIE,
VariableDIE.getDeclLine()};
}
-static void displayParents(SmallVector<DWARFDie> Parents, raw_ostream &OS) {
+static void displayParents(ArrayRef<DWARFDie> Parents, raw_ostream &OS) {
bool First = true;
for (const auto Parent : Parents) {
if (auto FormValue = Parent.find(DW_AT_call_file)) {
@@ -494,7 +504,7 @@ static void displayVariableCoverage(const VarKey &Key, const VarCoverage &Var,
<< format("%.3g", ((float)Var.LTCov / Var.Instances)) << "\t"
<< format("%.3g", ((float)Var.LTCov / Var.BaselineCov));
OS << "\n";
- if (Var.MissingBaseline)
+ if (Var.getMissingBaseline())
WithColor(errs(), HighlightColor::Warning).warning()
<< "DIE not found in baseline\n";
if (Var.Missing)
@@ -596,7 +606,7 @@ bool dwarfdump::showVariableCoverage(ObjectFile &Obj, DWARFContext &DICtx,
for (const auto &L : BCov)
VarCov.LTCov += SubroutineCov.count(L);
} else {
- VarCov.MissingBaseline = true;
+ VarCov.setMissingBaseline(true);
}
}
@@ -628,7 +638,11 @@ bool dwarfdump::showVariableCoverage(ObjectFile &Obj, DWARFContext &DICtx,
CombinedCov.BaselineCov += Var->second.BaselineCov;
CombinedCov.LTCov += Var->second.LTCov;
CombinedCov.Missing += Var->second.Missing;
- CombinedCov.MissingBaseline |= Var->second.MissingBaseline;
+ [&] {
+ auto PackedFlagValue = Var->second.getMissingBaseline();
+ return CombinedCov.setMissingBaseline(
+ CombinedCov.getMissingBaseline() | PackedFlagValue);
+ }();
}
displayVariableCoverage(FirstVar->first, CombinedCov, true, OS);
}
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index da21787c5096c..d653f44dfbefe 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -402,7 +402,9 @@ static DIDumpOptions getDumpOpts(DWARFContext &C) {
DumpOpts.ShowAddresses = !Diff;
DumpOpts.ShowChildren = ShowChildren;
DumpOpts.ShowParents = ShowParents;
- DumpOpts.FilterChildTag = makeTagVector(FilterChildTag);
+ auto ChildTags = makeTagVector(FilterChildTag);
+ DumpOpts.FilterChildTag = decltype(DumpOpts.FilterChildTag)(
+ DumpOpts.FilterChildTag.getFlags(), std::move(ChildTags));
DumpOpts.ShowForm = ShowForm;
DumpOpts.SummarizeTypes = SummarizeTypes;
DumpOpts.Verbose = Verbose;
@@ -415,8 +417,8 @@ static DIDumpOptions getDumpOpts(DWARFContext &C) {
if (Verify) {
DumpOpts.Verbose = ErrorDetails != NoDetailsOnlySummary &&
ErrorDetails != NoDetailsOrSummary;
- DumpOpts.ShowAggregateErrors = ErrorDetails != OnlyDetailsNoSummary &&
- ErrorDetails != NoDetailsOnlySummary;
+ DumpOpts.setShowAggregateErrors(ErrorDetails != OnlyDetailsNoSummary &&
+ ErrorDetails != NoDetailsOnlySummary);
DumpOpts.JsonErrSummaryFile = JsonErrSummaryFile;
return DumpOpts.noImplicitRecursion();
}
diff --git a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
index 2176db14f06f4..d04470a922319 100644
--- a/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
+++ b/llvm/tools/llvm-dwarfutil/llvm-dwarfutil.cpp
@@ -244,7 +244,7 @@ static Expected<uint32_t> saveSeparateDebugInfo(const Options &Opts,
std::string OutputFilename = Opts.getSeparateDebugFileName();
Config.Common.InputFilename = Opts.InputFileName;
Config.Common.OutputFilename = OutputFilename;
- Config.Common.OnlyKeepDebug = true;
+ Config.Common.setOnlyKeepDebug(true);
uint32_t WrittenFileCRC32 = 0;
if (Error Err = writeToOutput(
@@ -267,7 +267,7 @@ static Error saveNonDebugInfo(const Options &Opts, ObjectFile &InputFile,
objcopy::ConfigManager Config;
Config.Common.InputFilename = Opts.InputFileName;
Config.Common.OutputFilename = Opts.OutputFileName;
- Config.Common.StripDebug = true;
+ Config.Common.setStripDebug(true);
std::string SeparateDebugFileName = Opts.getSeparateDebugFileName();
Config.Common.AddGnuDebugLink = sys::path::filename(SeparateDebugFileName);
Config.Common.GnuDebugLinkCRC32 = GnuDebugLinkCRC32;
@@ -350,8 +350,8 @@ saveSeparateLinkedDebugInfo(const Options &Opts, ObjectFile &InputFile,
std::string OutputFilename = Opts.getSeparateDebugFileName();
Config.Common.InputFilename = Opts.InputFileName;
Config.Common.OutputFilename = OutputFilename;
- Config.Common.StripDebug = true;
- Config.Common.OnlyKeepDebug = true;
+ Config.Common.setStripDebug(true);
+ Config.Common.setOnlyKeepDebug(true);
uint32_t WrittenFileCRC32 = 0;
if (Error Err =
@@ -381,7 +381,7 @@ static Error saveSingleLinkedDebugInfo(const Options &Opts,
Config.Common.InputFilename = Opts.InputFileName;
Config.Common.OutputFilename = Opts.OutputFileName;
- Config.Common.StripDebug = true;
+ Config.Common.setStripDebug(true);
if (Error Err =
addSectionsFromLinkedData(Config, InputFile, LinkedDebugInfoBits))
return Err;
diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
index da0367f3fdbd6..4d71174dcf7f7 100644
--- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
@@ -361,7 +361,7 @@ void Analysis::printSchedClassDescHtml(const ResolvedSchedClass &RSC,
const auto &SI = State_.getSubtargetInfo();
const auto &SM = SI.getSchedModel();
OS << "<tr><td>✔</td>";
- OS << "<td>" << (RSC.WasVariant ? "✔" : "✕") << "</td>";
+ OS << "<td>" << (RSC.getWasVariant() ? "✔" : "✕") << "</td>";
OS << "<td>" << RSC.SCDesc->NumMicroOps << "</td>";
// Latencies.
OS << "<td><ul>";
diff --git a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
index 2cfbc6b91b9be..e98db2e2f8924 100644
--- a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
@@ -236,10 +236,12 @@ ResolvedSchedClass::ResolvedSchedClass(const MCSubtargetInfo &STI,
bool WasVariant)
: SchedClassId(ResolvedSchedClassId),
SCDesc(STI.getSchedModel().getSchedClassDesc(ResolvedSchedClassId)),
- WasVariant(WasVariant),
- NonRedundantWriteProcRes(getNonRedundantWriteProcRes(*SCDesc, STI)),
+ NonRedundantWriteProcRes(unsigned(WasVariant),
+ getNonRedundantWriteProcRes(*SCDesc, STI)),
IdealizedProcResPressure(computeIdealizedProcResPressure(
- STI.getSchedModel(), NonRedundantWriteProcRes)) {
+ STI.getSchedModel(), SmallVector<MCWriteProcResEntry, 8>(
+ NonRedundantWriteProcRes.begin(),
+ NonRedundantWriteProcRes.end()))) {
assert((SCDesc == nullptr || !SCDesc->isVariant()) &&
"ResolvedSchedClass should never be variant");
}
diff --git a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.h b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.h
index 2347449b8f23d..1f02c377a2ac6 100644
--- a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.h
+++ b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.h
@@ -15,6 +15,7 @@
#define LLVM_TOOLS_LLVM_EXEGESIS_SCHEDCLASSRESOLUTION_H
#include "BenchmarkResult.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInstPrinter.h"
@@ -50,8 +51,11 @@ struct ResolvedSchedClass {
const unsigned SchedClassId;
const MCSchedClassDesc *const SCDesc;
- const bool WasVariant; // Whether the original class was variant.
- const SmallVector<MCWriteProcResEntry, 8> NonRedundantWriteProcRes;
+ bool getWasVariant() const {
+ return NonRedundantWriteProcRes.getFlag(0);
+ } // Whether the original class was variant.
+ const llvm::SmallVectorWithFlags<MCWriteProcResEntry, 8>
+ NonRedundantWriteProcRes;
const std::vector<std::pair<uint16_t, float>> IdealizedProcResPressure;
};
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 4c0f9d1d09daf..ca91aa5f5a24d 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -1072,19 +1072,19 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
"bad format for --extract-section, expected section=file");
Config.ExtractSection.push_back(Value);
}
- Config.StripAll = InputArgs.hasArg(OBJCOPY_strip_all);
- Config.StripAllGNU = InputArgs.hasArg(OBJCOPY_strip_all_gnu);
- Config.StripDebug = InputArgs.hasArg(OBJCOPY_strip_debug);
- Config.StripDWO = InputArgs.hasArg(OBJCOPY_strip_dwo);
- Config.StripSections = InputArgs.hasArg(OBJCOPY_strip_sections);
- Config.StripNonAlloc = InputArgs.hasArg(OBJCOPY_strip_non_alloc);
- Config.StripUnneeded = InputArgs.hasArg(OBJCOPY_strip_unneeded);
- Config.ExtractDWO = InputArgs.hasArg(OBJCOPY_extract_dwo);
- Config.ExtractMainPartition =
- InputArgs.hasArg(OBJCOPY_extract_main_partition);
- ELFConfig.LocalizeHidden = InputArgs.hasArg(OBJCOPY_localize_hidden);
- Config.Verbose = InputArgs.hasArg(OBJCOPY_verbose);
- Config.Weaken = InputArgs.hasArg(OBJCOPY_weaken);
+ Config.setStripAll(InputArgs.hasArg(OBJCOPY_strip_all));
+ Config.setStripAllGNU(InputArgs.hasArg(OBJCOPY_strip_all_gnu));
+ Config.setStripDebug(InputArgs.hasArg(OBJCOPY_strip_debug));
+ Config.setStripDWO(InputArgs.hasArg(OBJCOPY_strip_dwo));
+ Config.setStripSections(InputArgs.hasArg(OBJCOPY_strip_sections));
+ Config.setStripNonAlloc(InputArgs.hasArg(OBJCOPY_strip_non_alloc));
+ Config.setStripUnneeded(InputArgs.hasArg(OBJCOPY_strip_unneeded));
+ Config.setExtractDWO(InputArgs.hasArg(OBJCOPY_extract_dwo));
+ Config.setExtractMainPartition(
+ InputArgs.hasArg(OBJCOPY_extract_main_partition));
+ ELFConfig.setLocalizeHidden(InputArgs.hasArg(OBJCOPY_localize_hidden));
+ Config.setVerbose(InputArgs.hasArg(OBJCOPY_verbose));
+ Config.setWeaken(InputArgs.hasArg(OBJCOPY_weaken));
if (auto *Arg =
InputArgs.getLastArg(OBJCOPY_discard_all, OBJCOPY_discard_locals)) {
Config.DiscardMode = Arg->getOption().matches(OBJCOPY_discard_all)
@@ -1092,17 +1092,17 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
: DiscardType::Locals;
}
- ELFConfig.VerifyNoteSections = InputArgs.hasFlag(
- OBJCOPY_verify_note_sections, OBJCOPY_no_verify_note_sections, true);
+ ELFConfig.setVerifyNoteSections(InputArgs.hasFlag(
+ OBJCOPY_verify_note_sections, OBJCOPY_no_verify_note_sections, true));
- Config.OnlyKeepDebug = InputArgs.hasArg(OBJCOPY_only_keep_debug);
- ELFConfig.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
+ Config.setOnlyKeepDebug(InputArgs.hasArg(OBJCOPY_only_keep_debug));
+ ELFConfig.setKeepFileSymbols(InputArgs.hasArg(OBJCOPY_keep_file_symbols));
MachOConfig.KeepUndefined = InputArgs.hasArg(OBJCOPY_keep_undefined);
- Config.DecompressDebugSections =
- InputArgs.hasArg(OBJCOPY_decompress_debug_sections);
+ Config.setDecompressDebugSections(
+ InputArgs.hasArg(OBJCOPY_decompress_debug_sections));
if (Config.DiscardMode == DiscardType::All) {
- Config.StripDebug = true;
- ELFConfig.KeepFileSymbols = true;
+ Config.setStripDebug(true);
+ ELFConfig.setKeepFileSymbols(true);
}
for (auto *Arg : InputArgs.filtered(OBJCOPY_localize_symbol))
if (Error E = Config.SymbolsToLocalize.addMatcher(NameOrPattern::create(
@@ -1212,15 +1212,15 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
return std::move(E);
}
- ELFConfig.AllowBrokenLinks = InputArgs.hasArg(OBJCOPY_allow_broken_links);
+ ELFConfig.setAllowBrokenLinks(InputArgs.hasArg(OBJCOPY_allow_broken_links));
- Config.DeterministicArchives = InputArgs.hasFlag(
+ Config.setDeterministicArchives(InputArgs.hasFlag(
OBJCOPY_enable_deterministic_archives,
- OBJCOPY_disable_deterministic_archives, /*default=*/true);
+ OBJCOPY_disable_deterministic_archives, /*default=*/true));
- Config.PreserveDates = InputArgs.hasArg(OBJCOPY_preserve_dates);
+ Config.setPreserveDates(InputArgs.hasArg(OBJCOPY_preserve_dates));
- if (Config.PreserveDates &&
+ if (Config.getPreserveDates() &&
(Config.OutputFilename == "-" || Config.InputFilename == "-"))
return createStringError(errc::invalid_argument,
"--preserve-dates requires a file");
@@ -1269,7 +1269,7 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
"cannot specify both --remove-note and --update-section");
}
- if (Config.DecompressDebugSections &&
+ if (Config.getDecompressDebugSections() &&
Config.CompressionType != DebugCompressionType::None) {
return createStringError(
errc::invalid_argument,
@@ -1277,7 +1277,7 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
"--decompress-debug-sections");
}
- if (Config.ExtractPartition && Config.ExtractMainPartition)
+ if (Config.ExtractPartition && Config.getExtractMainPartition())
return createStringError(errc::invalid_argument,
"cannot specify --extract-partition together with "
"--extract-main-partition");
@@ -1566,21 +1566,21 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
= InputArgs.hasArg(STRIP_regex) ? MatchStyle::Regex
: InputArgs.hasArg(STRIP_wildcard) ? MatchStyle::Wildcard
: MatchStyle::Literal;
- ELFConfig.AllowBrokenLinks = InputArgs.hasArg(STRIP_allow_broken_links);
- Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug);
+ ELFConfig.setAllowBrokenLinks(InputArgs.hasArg(STRIP_allow_broken_links));
+ Config.setStripDebug(InputArgs.hasArg(STRIP_strip_debug));
if (auto *Arg = InputArgs.getLastArg(STRIP_discard_all, STRIP_discard_locals))
Config.DiscardMode = Arg->getOption().matches(STRIP_discard_all)
? DiscardType::All
: DiscardType::Locals;
- Config.StripSections = InputArgs.hasArg(STRIP_strip_sections);
- Config.StripUnneeded = InputArgs.hasArg(STRIP_strip_unneeded);
+ Config.setStripSections(InputArgs.hasArg(STRIP_strip_sections));
+ Config.setStripUnneeded(InputArgs.hasArg(STRIP_strip_unneeded));
if (auto Arg = InputArgs.getLastArg(STRIP_strip_all, STRIP_no_strip_all))
- Config.StripAll = Arg->getOption().getID() == STRIP_strip_all;
- Config.StripAllGNU = InputArgs.hasArg(STRIP_strip_all_gnu);
+ Config.setStripAll(Arg->getOption().getID() == STRIP_strip_all);
+ Config.setStripAllGNU(InputArgs.hasArg(STRIP_strip_all_gnu));
MachOConfig.StripSwiftSymbols = InputArgs.hasArg(STRIP_strip_swift_symbols);
- Config.OnlyKeepDebug = InputArgs.hasArg(STRIP_only_keep_debug);
- ELFConfig.KeepFileSymbols = InputArgs.hasArg(STRIP_keep_file_symbols);
+ Config.setOnlyKeepDebug(InputArgs.hasArg(STRIP_only_keep_debug));
+ ELFConfig.setKeepFileSymbols(InputArgs.hasArg(STRIP_keep_file_symbols));
MachOConfig.KeepUndefined = InputArgs.hasArg(STRIP_keep_undefined);
for (auto *Arg : InputArgs.filtered(STRIP_keep_section))
@@ -1603,23 +1603,23 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
return std::move(E);
- if (!InputArgs.hasArg(STRIP_no_strip_all) && !Config.StripDebug &&
- !Config.OnlyKeepDebug && !Config.StripUnneeded &&
- Config.DiscardMode == DiscardType::None && !Config.StripAllGNU &&
+ if (!InputArgs.hasArg(STRIP_no_strip_all) && !Config.getStripDebug() &&
+ !Config.getOnlyKeepDebug() && !Config.getStripUnneeded() &&
+ Config.DiscardMode == DiscardType::None && !Config.getStripAllGNU() &&
Config.SymbolsToRemove.empty())
- Config.StripAll = true;
+ Config.setStripAll(true);
if (Config.DiscardMode == DiscardType::All) {
- Config.StripDebug = true;
- ELFConfig.KeepFileSymbols = true;
+ Config.setStripDebug(true);
+ ELFConfig.setKeepFileSymbols(true);
}
- Config.DeterministicArchives =
- InputArgs.hasFlag(STRIP_enable_deterministic_archives,
- STRIP_disable_deterministic_archives, /*default=*/true);
+ Config.setDeterministicArchives(InputArgs.hasFlag(
+ STRIP_enable_deterministic_archives, STRIP_disable_deterministic_archives,
+ /*default=*/true));
- Config.PreserveDates = InputArgs.hasArg(STRIP_preserve_dates);
- Config.Verbose = InputArgs.hasArg(STRIP_verbose);
+ Config.setPreserveDates(InputArgs.hasArg(STRIP_preserve_dates));
+ Config.setVerbose(InputArgs.hasArg(STRIP_verbose));
Config.InputFormat = FileFormat::Unspecified;
Config.OutputFormat = FileFormat::Unspecified;
@@ -1648,8 +1648,9 @@ objcopy::parseStripOptions(ArrayRef<const char *> RawArgsArr,
}
}
- if (Config.PreserveDates && (is_contained(Positional, "-") ||
- InputArgs.getLastArgValue(STRIP_output) == "-"))
+ if (Config.getPreserveDates() &&
+ (is_contained(Positional, "-") ||
+ InputArgs.getLastArgValue(STRIP_output) == "-"))
return createStringError(errc::invalid_argument,
"--preserve-dates requires a file");
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index 1b98b4bc1a772..51d347a214e5c 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -172,7 +172,7 @@ static Error executeObjcopy(ConfigManager &ConfigMgr) {
return createFileError(Config.InputFilename, BufOrErr.getError());
MemoryBufferHolder = std::move(*BufOrErr);
- if (Config.Verbose)
+ if (Config.getVerbose())
printCopyMessage(
Config.InputFilename, toFileFormatName(Config.InputFormat),
Config.OutputFilename, toFileFormatName(Config.OutputFormat));
@@ -199,7 +199,7 @@ static Error executeObjcopy(ConfigManager &ConfigMgr) {
if (Error E = executeObjcopyOnArchive(ConfigMgr, *Ar))
return E;
} else {
- if (Config.Verbose)
+ if (Config.getVerbose())
printCopyMessage(Config.InputFilename,
getObjectFormatName(*BinaryHolder.getBinary()),
Config.OutputFilename,
@@ -219,14 +219,14 @@ static Error executeObjcopy(ConfigManager &ConfigMgr) {
if (Error E = writeToOutput(Config.OutputFilename, ObjcopyFunc))
return E;
} else {
- Config.ExtractDWO = true;
- Config.StripDWO = false;
+ Config.setExtractDWO(true);
+ Config.setStripDWO(false);
// Copy .dwo tables from the Config.InputFilename into Config.SplitDWO
// file using specified ObjcopyFunc function.
if (Error E = writeToOutput(Config.SplitDWO, ObjcopyFunc))
return E;
- Config.ExtractDWO = false;
- Config.StripDWO = true;
+ Config.setExtractDWO(false);
+ Config.setStripDWO(true);
// Apply transformations described by Config, remove .dwo tables and
// store result into Config.OutputFilename using specified ObjcopyFunc
// function.
@@ -235,13 +235,13 @@ static Error executeObjcopy(ConfigManager &ConfigMgr) {
}
}
- if (Error E =
- PermsApplierOrErr->apply(Config.OutputFilename, Config.PreserveDates))
+ if (Error E = PermsApplierOrErr->apply(Config.OutputFilename,
+ Config.getPreserveDates()))
return E;
if (!Config.SplitDWO.empty())
if (Error E =
- PermsApplierOrErr->apply(Config.SplitDWO, Config.PreserveDates,
+ PermsApplierOrErr->apply(Config.SplitDWO, Config.getPreserveDates(),
static_cast<sys::fs::perms>(0666)))
return E;
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index a47391c81ef21..384c096e8f6ea 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -187,7 +187,9 @@ void VirtualUnwinder::unwindBranch(UnwindState &State) {
std::shared_ptr<StringBasedCtxKey> FrameStack::getContextKey() {
std::shared_ptr<StringBasedCtxKey> KeyStr =
std::make_shared<StringBasedCtxKey>();
- KeyStr->Context = Binary->getExpandedContext(Stack, KeyStr->WasLeafInlined);
+ bool WasLeafInlined = KeyStr->getWasLeafInlined();
+ KeyStr->Context.assign(Binary->getExpandedContext(Stack, WasLeafInlined));
+ KeyStr->setWasLeafInlined(WasLeafInlined);
return KeyStr;
}
@@ -1084,7 +1086,9 @@ void UnsymbolizedProfileReader::readUnsymbolizedProfile(StringRef FileName) {
if (Line.starts_with("[")) {
ProfileIsCS = true;
auto I = ContextStrSet.insert(Line);
- SampleContext::createCtxVectorFromStr(I.first->getKey(), Key->Context);
+ SampleContextFrameVector Context;
+ SampleContext::createCtxVectorFromStr(I.first->getKey(), Context);
+ Key->Context.assign(std::move(Context));
TraceIt.advance();
}
auto Ret = SampleCounters.try_emplace(Hashable<ContextKey>(Key));
diff --git a/llvm/tools/llvm-profgen/PerfReader.h b/llvm/tools/llvm-profgen/PerfReader.h
index 04f8388fc2f0d..66c4754eacf30 100644
--- a/llvm/tools/llvm-profgen/PerfReader.h
+++ b/llvm/tools/llvm-profgen/PerfReader.h
@@ -11,6 +11,7 @@
#include "ErrorHandling.h"
#include "ProfiledBinary.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
@@ -335,17 +336,20 @@ struct ContextKey {
// String based context id
struct StringBasedCtxKey : public ContextKey {
- SampleContextFrameVector Context;
+ llvm::SmallVectorWithFlagsFor<SampleContextFrameVector, 1> Context;
- bool WasLeafInlined;
- StringBasedCtxKey() : ContextKey(CK_StringBased), WasLeafInlined(false){};
+ bool getWasLeafInlined() const { return Context.getFlag(0); }
+ void setWasLeafInlined(bool Value) { Context.setFlag(0, Value); }
+ StringBasedCtxKey() : ContextKey(CK_StringBased) {};
static bool classof(const ContextKey *K) {
return K->getKind() == CK_StringBased;
}
bool isEqual(const ContextKey *K) const override {
const StringBasedCtxKey *Other = dyn_cast<StringBasedCtxKey>(K);
- return Context == Other->Context;
+ return (
+ llvm::ArrayRef<llvm::sampleprof::SampleContextFrame>(Context) ==
+ llvm::ArrayRef<llvm::sampleprof::SampleContextFrame>(Other->Context));
}
void genHashCode() override {
@@ -357,8 +361,7 @@ struct StringBasedCtxKey : public ContextKey {
struct AddrBasedCtxKey : public ContextKey {
SmallVector<uint64_t, 16> Context;
- bool WasLeafInlined;
- AddrBasedCtxKey() : ContextKey(CK_AddrBased), WasLeafInlined(false){};
+ AddrBasedCtxKey() : ContextKey(CK_AddrBased) {}
static bool classof(const ContextKey *K) {
return K->getKind() == CK_AddrBased;
}
diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp
index efc2d91bbb064..0e563c335cb43 100644
--- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp
+++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp
@@ -991,7 +991,7 @@ void CSProfileGenerator::generateLineNumBasedProfile() {
if (!CtxKey->Context.empty()) {
// Get or create function profile for the range
ContextNode =
- getOrCreateContextNode(CtxKey->Context, CtxKey->WasLeafInlined);
+ getOrCreateContextNode(CtxKey->Context, CtxKey->getWasLeafInlined());
// Fill in function body samples
populateBodySamplesForFunction(*ContextNode->getFunctionSamples(),
CI.second.RangeCounter);
diff --git a/llvm/tools/llvm-reduce/TestRunner.cpp b/llvm/tools/llvm-reduce/TestRunner.cpp
index ad9f925ebccc7..26ee104391071 100644
--- a/llvm/tools/llvm-reduce/TestRunner.cpp
+++ b/llvm/tools/llvm-reduce/TestRunner.cpp
@@ -18,9 +18,11 @@ TestRunner::TestRunner(StringRef TestName, ArrayRef<std::string> RawTestArgs,
std::unique_ptr<TargetMachine> TM, StringRef ToolName,
StringRef OutputName, bool InputIsBitcode,
bool OutputBitcode)
- : TestName(TestName), ToolName(ToolName), Program(std::move(Program)),
- TM(std::move(TM)), OutputFilename(OutputName),
- InputIsBitcode(InputIsBitcode), EmitBitcode(OutputBitcode) {
+ : TestName(TestName), ToolName(ToolName),
+ TestArgs(decltype(this->TestArgs)::withFlags(
+ unsigned(InputIsBitcode) | (unsigned(OutputBitcode) << 1))),
+ Program(std::move(Program)), TM(std::move(TM)),
+ OutputFilename(OutputName) {
assert(this->Program && "Initialized with null program?");
TestArgs.push_back(TestName); // argv[0]
@@ -34,7 +36,7 @@ static constexpr std::array<std::optional<StringRef>, 3> NullRedirects;
/// Runs the interestingness test, passes file to be tested as first argument
/// and other specified test arguments after that.
int TestRunner::run(StringRef Filename) const {
- SmallVector<StringRef> ExecArgs(TestArgs);
+ SmallVector<StringRef> ExecArgs(TestArgs.begin(), TestArgs.end());
ExecArgs.push_back(Filename);
std::string ErrMsg;
@@ -57,14 +59,14 @@ int TestRunner::run(StringRef Filename) const {
void TestRunner::writeOutput(StringRef Message) {
std::error_code EC;
raw_fd_ostream Out(OutputFilename, EC,
- EmitBitcode && !Program->isMIR() ? sys::fs::OF_None
- : sys::fs::OF_Text);
+ getEmitBitcode() && !Program->isMIR() ? sys::fs::OF_None
+ : sys::fs::OF_Text);
if (EC) {
WithColor::error(errs(), ToolName)
<< "opening output file: " << EC.message() << '\n';
exit(1);
}
- Program->writeOutput(Out, EmitBitcode);
+ Program->writeOutput(Out, getEmitBitcode());
errs() << Message << OutputFilename << '\n';
}
diff --git a/llvm/tools/llvm-reduce/TestRunner.h b/llvm/tools/llvm-reduce/TestRunner.h
index 0218dad263b05..a2bd5afe527fc 100644
--- a/llvm/tools/llvm-reduce/TestRunner.h
+++ b/llvm/tools/llvm-reduce/TestRunner.h
@@ -10,6 +10,7 @@
#define LLVM_TOOLS_LLVM_REDUCE_TESTRUNNER_H
#include "ReducerWorkItem.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
@@ -47,19 +48,27 @@ class TestRunner {
void writeOutput(StringRef Message);
- bool inputIsBitcode() const {
- return InputIsBitcode;
- }
+ bool inputIsBitcode() const { return getInputIsBitcode(); }
private:
StringRef TestName;
StringRef ToolName;
- SmallVector<StringRef> TestArgs;
+ llvm::SmallVectorWithFlags<
+ StringRef,
+ llvm::CalculateSmallVectorDefaultInlinedElements<StringRef>::value, 2>
+ TestArgs;
std::unique_ptr<ReducerWorkItem> Program;
std::unique_ptr<TargetMachine> TM;
StringRef OutputFilename;
- const bool InputIsBitcode;
- bool EmitBitcode;
+ bool getInputIsBitcode() const { return TestArgs.getFlag(0); }
+ bool getEmitBitcode() const { return TestArgs.getFlag(1); }
+ void setEmitBitcode(bool Value) { TestArgs.setFlag(1, Value); }
+
+public:
+ TestRunner(const TestRunner &) = default;
+ TestRunner(TestRunner &&) = default;
+ TestRunner &operator=(const TestRunner &) = delete;
+ TestRunner &operator=(TestRunner &&) = delete;
};
} // namespace llvm
diff --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
index 455dfd9a89cef..b1ef1c70ee43d 100644
--- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
@@ -197,7 +198,7 @@ class TrivialMemoryManager : public RTDyldMemoryManager {
};
SmallVector<SectionInfo, 16> FunctionMemory;
- SmallVector<SectionInfo, 16> DataMemory;
+ llvm::SmallVectorWithFlags<SectionInfo, 16> DataMemory;
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID,
@@ -258,7 +259,7 @@ class TrivialMemoryManager : public RTDyldMemoryManager {
EC.message());
PreallocSlab = MB;
- UsePreallocation = true;
+ setUsePreallocation(true);
SlabSize = Size;
}
@@ -281,7 +282,8 @@ class TrivialMemoryManager : public RTDyldMemoryManager {
private:
std::map<std::string, uint64_t> DummyExterns;
sys::MemoryBlock PreallocSlab;
- bool UsePreallocation = false;
+ bool getUsePreallocation() const { return DataMemory.getFlag(0); }
+ void setUsePreallocation(bool Value) { DataMemory.setFlag(0, Value); }
uintptr_t SlabSize = 0;
uintptr_t CurrentSlabOffset = 0;
SectionIDMap *SecIDMap = nullptr;
@@ -301,7 +303,7 @@ uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
if (SecIDMap)
(*SecIDMap)[SectionName] = SectionID;
- if (UsePreallocation)
+ if (getUsePreallocation())
return allocateFromSlab(Size, Alignment, true /* isCode */,
SectionName, SectionID);
@@ -330,7 +332,7 @@ uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
if (SecIDMap)
(*SecIDMap)[SectionName] = SectionID;
- if (UsePreallocation)
+ if (getUsePreallocation())
return allocateFromSlab(Size, Alignment, false /* isCode */, SectionName,
SectionID);
diff --git a/llvm/unittests/ADT/SmallVectorWithFlagsTest.cpp b/llvm/unittests/ADT/SmallVectorWithFlagsTest.cpp
index ada094ef83da3..e0e19cda42f98 100644
--- a/llvm/unittests/ADT/SmallVectorWithFlagsTest.cpp
+++ b/llvm/unittests/ADT/SmallVectorWithFlagsTest.cpp
@@ -72,6 +72,10 @@ TYPED_TEST(SmallVectorWithFlagsTypedTest,
T *Data = V.data();
size_t Capacity = V.capacity();
for (unsigned Flags = 0; Flags < (1u << TypeParam::NumFlagBits); ++Flags) {
+ TypeParam Constructed = TypeParam::withFlags(Flags, Size, element<T>(3));
+ EXPECT_EQ(Flags, Constructed.getFlags());
+ EXPECT_EQ(Size, Constructed.size());
+ EXPECT_EQ(ArrayRef<T>(V), ArrayRef<T>(Constructed));
V.setFlags(Flags);
EXPECT_EQ(Flags, V.getFlags());
for (unsigned Bit = 0; Bit < TypeParam::NumFlagBits; ++Bit)
@@ -116,10 +120,9 @@ TYPED_TEST(SmallVectorWithFlagsTypedTest, CapacityMatchesPlainSmallVector) {
}
TYPED_TEST(SmallVectorWithFlagsTypedTest, ElementOperationsPreserveFlags) {
- TypeParam V;
using T = typename TypeParam::value_type;
unsigned Flags = (1u << TypeParam::NumFlagBits) - 1;
- V.setFlags(Flags);
+ TypeParam V = TypeParam::withFlags(Flags);
for (unsigned I = 0; I < 32; ++I) {
V.push_back(element<T>(I));
EXPECT_EQ(Flags, V.getFlags());
@@ -509,6 +512,74 @@ struct MoveConstructOnly {
int Value;
};
+TEST(SmallVectorWithFlagsTest, MoveFromPlainVectorWithExplicitFlags) {
+ for (unsigned Size : {0u, 1u, 16u}) {
+ SmallVector<MoveConstructOnly, 1> Source;
+ for (unsigned I = 0; I < Size; ++I)
+ Source.emplace_back(I);
+ MoveConstructOnly *Data = Source.data();
+ SmallVectorWithFlagsFor<decltype(Source), 2> Dest(3, std::move(Source));
+ EXPECT_EQ(Dest.getFlags(), 3u);
+ EXPECT_EQ(Dest.size(), Size);
+ EXPECT_TRUE(Source.empty());
+ if (Size > 1)
+ EXPECT_EQ(Dest.data(), Data);
+ for (unsigned I = 0; I < Size; ++I)
+ EXPECT_EQ(Dest[I].Value, static_cast<int>(I));
+ }
+}
+
+TEST(SmallVectorWithFlagsTest, AssignPlainVectorPreservesFlags) {
+ for (unsigned Size : {0u, 1u, 16u}) {
+ for (bool Reserve : {false, true}) {
+ SmallVector<int, 1> Source(Size, 7);
+ if (Reserve)
+ Source.reserve(32);
+ int *Data = Source.data();
+ bool HasHeapBuffer = Source.capacity() > 1;
+ SmallVectorWithFlags<int, 2, 2> Dest{1, 2, 3};
+ Dest.setFlags(3);
+ Dest.assign(std::move(Source));
+ EXPECT_EQ(Dest.getFlags(), 3u);
+ EXPECT_EQ(Dest.size(), Size);
+ EXPECT_TRUE(Source.empty());
+ if (HasHeapBuffer)
+ EXPECT_EQ(Dest.data(), Data);
+ for (int Value : Dest)
+ EXPECT_EQ(Value, 7);
+
+ // Output interfaces can temporarily own the elements in a plain vector.
+ // Retain both the flags and an empty reserved buffer across that loan.
+ SmallVector<int, 2> Payload;
+ Payload = std::move(Dest);
+ EXPECT_TRUE(Dest.empty());
+ EXPECT_EQ(Dest.getFlags(), 3u);
+ if (HasHeapBuffer)
+ EXPECT_EQ(Payload.data(), Data);
+ Dest.assign(std::move(Payload));
+ EXPECT_EQ(Dest.getFlags(), 3u);
+ EXPECT_EQ(Dest.size(), Size);
+ if (HasHeapBuffer)
+ EXPECT_EQ(Dest.data(), Data);
+ }
+ }
+
+ // Character vectors use a 64-bit capacity word on 64-bit hosts.
+ SmallVectorWithFlags<char, 0, 4> Buffer;
+ Buffer.setFlags(11);
+ Buffer.reserve(32);
+ char *Data = Buffer.data();
+ SmallVector<char, 0> Payload;
+ Payload = std::move(Buffer);
+ EXPECT_EQ(Payload.data(), Data);
+ EXPECT_EQ(Buffer.getFlags(), 11u);
+ Payload.append({'x', 'y', 'z'});
+ Buffer.assign(std::move(Payload));
+ EXPECT_EQ(Buffer.data(), Data);
+ EXPECT_EQ(Buffer.getFlags(), 11u);
+ EXPECT_THAT(Buffer, ElementsAre('x', 'y', 'z'));
+}
+
TEST(SmallVectorWithFlagsTest, MoveConstructNonMoveAssignableElements) {
for (unsigned Size : {0u, 1u, 16u}) {
SmallVectorWithFlags<MoveConstructOnly, 1> Source;
@@ -590,6 +661,41 @@ TEST(SmallVectorWithFlagsTest, MoveIntoPlainSmallVector) {
EXPECT_TRUE(MoveOnly.empty());
}
+TEST(SmallVectorWithFlagsTest, OrdinaryVectorConstruction) {
+ const SmallVector<int, 2> Plain = {1, 2, 3, 4};
+ SmallVectorWithFlags<int, 2, 3> Copy(Plain);
+ EXPECT_EQ(ArrayRef<int>(Copy), ArrayRef<int>(Plain));
+ EXPECT_EQ(Copy.getFlags(), 0u);
+ auto FlaggedCopy = decltype(Copy)::withFlags(5, Plain);
+ EXPECT_EQ(ArrayRef<int>(FlaggedCopy), ArrayRef<int>(Plain));
+ EXPECT_EQ(FlaggedCopy.getFlags(), 5u);
+
+ SmallVector<std::unique_ptr<int>, 1> Owned;
+ Owned.push_back(std::make_unique<int>(7));
+ Owned.push_back(std::make_unique<int>(9));
+ auto *Buffer = Owned.data();
+ SmallVectorWithFlags<std::unique_ptr<int>, 1, 3> Moved(std::move(Owned));
+ EXPECT_EQ(Moved.data(), Buffer);
+ EXPECT_EQ(*Moved[0], 7);
+ EXPECT_EQ(*Moved[1], 9);
+ EXPECT_EQ(Moved.getFlags(), 0u);
+ EXPECT_TRUE(Owned.empty());
+}
+
+TEST(SmallVectorWithFlagsTest, InitializerListAssignmentPreservesFlags) {
+ SmallVectorWithFlags<int, 2, 3> V;
+ V.setFlags(5);
+ V = {1, 2, 3, 4};
+ EXPECT_EQ(ArrayRef<int>(V), (ArrayRef<int>{1, 2, 3, 4}));
+ EXPECT_EQ(V.getFlags(), 5u);
+ V = {9};
+ EXPECT_EQ(ArrayRef<int>(V), (ArrayRef<int>{9}));
+ EXPECT_EQ(V.getFlags(), 5u);
+ V = {};
+ EXPECT_TRUE(V.empty());
+ EXPECT_EQ(V.getFlags(), 5u);
+}
+
TEST(SmallVectorWithFlagsTest, OwningElements) {
SmallVectorWithFlags<std::unique_ptr<int>, 1> V;
V.setFlag(0, true);
diff --git a/llvm/unittests/Bitstream/BitstreamWriterTest.cpp b/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
index 933965abdbadf..e68fa3c3e5604 100644
--- a/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
+++ b/llvm/unittests/Bitstream/BitstreamWriterTest.cpp
@@ -9,6 +9,7 @@
#include "llvm/Bitstream/BitstreamWriter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Bitstream/BitCodeEnums.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Support/Error.h"
@@ -21,6 +22,23 @@ using namespace llvm;
namespace {
+TEST(BitstreamWriterTest, OwnedBufferTransfer) {
+ SmallVectorWithFlags<char, 0> Bytes;
+ Bytes.setFlag(0, true);
+ {
+ BitstreamWriter Writer;
+ Writer.Emit(0x1234, 16);
+ Writer.FlushToWord();
+ auto *Buffer = Writer.getBuffer().data();
+ Bytes.assign(std::move(Writer.getBuffer()));
+ EXPECT_EQ(Bytes.data(), Buffer);
+ EXPECT_TRUE(Writer.getBuffer().empty());
+ }
+ EXPECT_TRUE(Bytes.getFlag(0));
+ EXPECT_EQ(StringRef(Bytes.data(), Bytes.size()),
+ StringRef("\x34\x12\0\0", 4));
+}
+
TEST(BitstreamWriterTest, emitBlob) {
SmallString<64> Buffer;
BitstreamWriter W(Buffer);
diff --git a/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp b/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp
index 2f5ae1ac52c1c..bd2a7f31e168d 100644
--- a/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp
+++ b/llvm/unittests/CodeGen/SelectionDAGNodeConstructionTest.cpp
@@ -9,7 +9,9 @@
#include "SelectionDAGTestBase.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/CodeGen/ISDOpcodes.h"
+#include "llvm/CodeGen/TargetLowering.h"
using namespace llvm;
@@ -538,3 +540,43 @@ TEST_F(SelectionDAGNodeConstructionTest, VectorRepeat) {
EXPECT_EQ(NXV1.getOperand(0).getOperand(0), V1);
EXPECT_TRUE(isNullConstant(NXV1.getOperand(0).getOperand(1)));
}
+
+TEST_F(SelectionDAGNodeConstructionTest, TokenFactorPreservesVectorFlags) {
+ SmallVectorWithFlags<SDValue, 8, 3> Chains;
+ Chains.setFlags(5);
+ Chains.assign(SDNode::getMaxNumOperands() + 1, DAG->getEntryNode());
+ SDValue Root = DAG->getTokenFactor(SDLoc(), Chains);
+ EXPECT_EQ(Root.getValueType(), MVT::Other);
+ EXPECT_EQ(Chains.size(), 2u);
+ EXPECT_EQ(Chains.getFlags(), 5u);
+}
+
+TEST_F(SelectionDAGNodeConstructionTest,
+ CallFlagsSurviveArgumentGrowthAndCopy) {
+ TargetLowering::CallLoweringInfo CLI(*DAG);
+ EXPECT_TRUE(CLI.getIsReturnValueUsed());
+ EXPECT_FALSE(CLI.getIsTailCall());
+ CLI.setSExtResult().setConvergent().setTailCall();
+ CLI.setNoMerge(true);
+ CLI.Outs.assign(65, ISD::OutputArg({}, MVT::i32, MVT::i32, nullptr, 0, 0));
+ CLI.Ins.assign(65,
+ ISD::InputArg({}, MVT::i32, MVT::i32, nullptr, true, 0, 0));
+ CLI.InVals.assign(17, DAG->getEntryNode());
+
+ auto Copy = CLI;
+ CLI.Outs.clear();
+ CLI.Ins.clear();
+ CLI.InVals.clear();
+ for (const auto *Info : {&CLI, &Copy}) {
+ EXPECT_TRUE(Info->getRetSExt());
+ EXPECT_TRUE(Info->getIsReturnValueUsed());
+ EXPECT_TRUE(Info->getIsConvergent());
+ EXPECT_TRUE(Info->getNoMerge());
+ EXPECT_TRUE(Info->getIsTailCall());
+ EXPECT_FALSE(Info->getRetZExt());
+ }
+ EXPECT_EQ(Copy.Outs.size(), 65u);
+ EXPECT_EQ(Copy.Ins.size(), 65u);
+ EXPECT_EQ(Copy.InVals.size(), 17u);
+ EXPECT_EQ(Copy.InVals.front(), DAG->getEntryNode());
+}
diff --git a/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
index 896315638634f..c0000b0182f21 100644
--- a/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
+++ b/llvm/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
@@ -8,6 +8,7 @@
#include "MCJITTestBase.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ExecutionEngine/MCJIT.h"
@@ -22,13 +23,13 @@ namespace {
class TestObjectCache : public ObjectCache {
public:
- TestObjectCache() : DuplicateInserted(false) { }
+ TestObjectCache() {}
void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override {
// If we've seen this module before, note that.
const std::string ModuleID = M->getModuleIdentifier();
if (ObjMap.contains(ModuleID))
- DuplicateInserted = true;
+ setDuplicateInserted(true);
// Store a copy of the buffer in our map.
ObjMap[ModuleID] = copyBuffer(Obj);
}
@@ -44,7 +45,7 @@ class TestObjectCache : public ObjectCache {
}
// Test-harness-specific functions
- bool wereDuplicatesInserted() { return DuplicateInserted; }
+ bool wereDuplicatesInserted() { return getDuplicateInserted(); }
bool wasModuleLookedUp(const Module *M) {
return ModulesLookedUp.contains(M->getModuleIdentifier());
@@ -71,8 +72,9 @@ class TestObjectCache : public ObjectCache {
StringMap<const MemoryBuffer *> ObjMap;
StringSet<> ModulesLookedUp;
- SmallVector<std::unique_ptr<MemoryBuffer>, 2> AllocatedBuffers;
- bool DuplicateInserted;
+ llvm::SmallVectorWithFlags<std::unique_ptr<MemoryBuffer>, 2> AllocatedBuffers;
+ bool getDuplicateInserted() const { return AllocatedBuffers.getFlag(0); }
+ void setDuplicateInserted(bool Value) { AllocatedBuffers.setFlag(0, Value); }
};
class MCJITObjectCacheTest : public testing::Test, public MCJITTestBase {
diff --git a/llvm/unittests/Frontend/HLSLSemanticSignaturePackingTest.cpp b/llvm/unittests/Frontend/HLSLSemanticSignaturePackingTest.cpp
index 6013c9d25500f..554c1e88f2012 100644
--- a/llvm/unittests/Frontend/HLSLSemanticSignaturePackingTest.cpp
+++ b/llvm/unittests/Frontend/HLSLSemanticSignaturePackingTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Frontend/HLSL/SemanticSignaturePacking.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Testing/Support/Error.h"
@@ -42,19 +43,20 @@ class HLSLSemanticSignaturePackingTest : public testing::Test {
struct TestConfig {
Triple::EnvironmentType ShaderStage;
IOType IOTy;
- bool UseNative16BitTypes;
- SmallVector<ElementConfig> Elements;
+ bool getUseNative16BitTypes() const { return Elements.getFlag(0); }
+ void setUseNative16BitTypes(bool Value) { Elements.setFlag(0, Value); }
+ llvm::SmallVectorWithFlags<ElementConfig> Elements;
TestConfig(Triple::EnvironmentType ShaderStage, IOType IOTy,
std::initializer_list<ElementConfig> Elements)
- : ShaderStage(ShaderStage), IOTy(IOTy), UseNative16BitTypes(false),
- Elements(Elements) {}
+ : ShaderStage(ShaderStage), IOTy(IOTy), Elements(Elements) {}
TestConfig(Triple::EnvironmentType ShaderStage, IOType IOTy,
bool UseNative16BitTypes,
std::initializer_list<ElementConfig> Elements)
: ShaderStage(ShaderStage), IOTy(IOTy),
- UseNative16BitTypes(UseNative16BitTypes), Elements(Elements) {}
+ Elements(decltype(this->Elements)::withFlags(
+ unsigned(UseNative16BitTypes), Elements)) {}
};
enum class PackingMethod {
@@ -95,10 +97,11 @@ class HLSLSemanticSignaturePackingTest : public testing::Test {
return packSignatureIndexed(Elements, Config.ShaderStage, Config.IOTy);
case PackingMethod::PrefixStable:
return packSignaturePrefixStable(Elements, Config.ShaderStage,
- Config.IOTy, Config.UseNative16BitTypes);
+ Config.IOTy,
+ Config.getUseNative16BitTypes());
case PackingMethod::Optimized:
return packSignatureOptimized(Elements, Config.ShaderStage, Config.IOTy,
- Config.UseNative16BitTypes);
+ Config.getUseNative16BitTypes());
}
llvm_unreachable("invalid packing method");
}
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
index e3e22ce05e6a4..2fb8362dfc4e7 100644
--- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
@@ -8721,7 +8721,7 @@ TEST_F(OpenMPIRBuilderTest, EmitOffloadingArraysNonContigCountExpression) {
CombinedInfo.Names.push_back(
Builder.CreateGlobalString("data", "data_name", 0, M.get()));
- CombinedInfo.NonContigInfo.IsNonContiguous = true;
+ CombinedInfo.NonContigInfo.setIsNonContiguous(true);
CombinedInfo.NonContigInfo.Dims.push_back(1);
CombinedInfo.NonContigInfo.Offsets.push_back({Builder.getInt64(0)});
CombinedInfo.NonContigInfo.Counts.push_back({CountExpr});
diff --git a/llvm/unittests/IR/LegacyPassManagerTest.cpp b/llvm/unittests/IR/LegacyPassManagerTest.cpp
index 3a3982763bb06..fbb64e8fd7e06 100644
--- a/llvm/unittests/IR/LegacyPassManagerTest.cpp
+++ b/llvm/unittests/IR/LegacyPassManagerTest.cpp
@@ -38,6 +38,29 @@
using namespace llvm;
+TEST(AnalysisUsageTest, PreservesAllAcrossUsedSetUpdatesAndCopies) {
+ char IDs[8] = {};
+ AnalysisUsage Usage;
+ EXPECT_FALSE(Usage.getPreservesAll());
+ Usage.setPreservesAll();
+ for (char &ID : IDs)
+ Usage.addUsedIfAvailableID(ID);
+ Usage.addUsedIfAvailableID(IDs[0]);
+ EXPECT_TRUE(Usage.getPreservesAll());
+ EXPECT_EQ(Usage.getUsedSet().size(), std::size(IDs));
+
+ AnalysisUsage Copy = Usage;
+ EXPECT_TRUE(Copy.getPreservesAll());
+ EXPECT_EQ(Copy.getUsedSet(), Usage.getUsedSet());
+ AnalysisUsage Moved = std::move(Copy);
+ EXPECT_TRUE(Moved.getPreservesAll());
+ EXPECT_EQ(Moved.getUsedSet(), Usage.getUsedSet());
+
+ Moved = AnalysisUsage();
+ EXPECT_FALSE(Moved.getPreservesAll());
+ EXPECT_TRUE(Moved.getUsedSet().empty());
+}
+
namespace llvm {
void initializeModuleNDMPass(PassRegistry &);
void initializeFPassPass(PassRegistry &);
diff --git a/llvm/unittests/MC/LoongArch/LoongArchMCDisassemblerTest.cpp b/llvm/unittests/MC/LoongArch/LoongArchMCDisassemblerTest.cpp
index de99f26945542..38ead8f982b98 100644
--- a/llvm/unittests/MC/LoongArch/LoongArchMCDisassemblerTest.cpp
+++ b/llvm/unittests/MC/LoongArch/LoongArchMCDisassemblerTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
@@ -79,12 +80,13 @@ class LoongArchMCSymbolizerTest : public MCSymbolizer {
explicit LoongArchMCSymbolizerTest(MCContext &Ctx)
: MCSymbolizer(Ctx, nullptr) {}
- SmallVector<Call, 1> Calls;
- bool AddSymbolicOperand = false;
+ llvm::SmallVectorWithFlags<Call, 1> Calls;
+ bool getAddSymbolicOperand() const { return Calls.getFlag(0); }
+ void setAddSymbolicOperand(bool Value) { Calls.setFlag(0, Value); }
void reset(bool AddSymbol = false) {
Calls.clear();
- AddSymbolicOperand = AddSymbol;
+ setAddSymbolicOperand(AddSymbol);
}
bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &CommentStream,
@@ -93,7 +95,7 @@ class LoongArchMCSymbolizerTest : public MCSymbolizer {
uint64_t InstSize) override {
Calls.push_back(
{&CommentStream, Value, Address, IsBranch, Offset, OpSize, InstSize});
- if (!AddSymbolicOperand)
+ if (!getAddSymbolicOperand())
return false;
Inst.addOperand(MCOperand::createExpr(
diff --git a/llvm/unittests/ProfileData/DataAccessProfTest.cpp b/llvm/unittests/ProfileData/DataAccessProfTest.cpp
index 2f93e16f28c1c..a1555fdb70c01 100644
--- a/llvm/unittests/ProfileData/DataAccessProfTest.cpp
+++ b/llvm/unittests/ProfileData/DataAccessProfTest.cpp
@@ -23,6 +23,7 @@ using ::testing::ElementsAre;
using ::testing::Field;
using ::testing::HasSubstr;
using ::testing::IsEmpty;
+using ::testing::Property;
static std::string ErrorToString(Error E) {
std::string ErrMsg;
@@ -155,18 +156,18 @@ TEST(MemProf, DataAccessProfile) {
ElementsAre(
AllOf(Field(&DataAccessProfRecordRef::SymbolID, 0),
Field(&DataAccessProfRecordRef::AccessCount, 100),
- Field(&DataAccessProfRecordRef::IsStringLiteral, false),
+ Property(&DataAccessProfRecordRef::isStringLiteral, false),
Field(&DataAccessProfRecordRef::Locations, IsEmpty())),
AllOf(Field(&DataAccessProfRecordRef::SymbolID, 2),
Field(&DataAccessProfRecordRef::AccessCount, 123),
- Field(&DataAccessProfRecordRef::IsStringLiteral, false),
+ Property(&DataAccessProfRecordRef::isStringLiteral, false),
Field(&DataAccessProfRecordRef::Locations,
ElementsAre(
AllOf(Field(&SourceLocationRef::FileName, "file2"),
Field(&SourceLocationRef::Line, 3))))),
AllOf(Field(&DataAccessProfRecordRef::SymbolID, 135246),
Field(&DataAccessProfRecordRef::AccessCount, 1000),
- Field(&DataAccessProfRecordRef::IsStringLiteral, true),
+ Property(&DataAccessProfRecordRef::isStringLiteral, true),
Field(&DataAccessProfRecordRef::Locations,
ElementsAre(
AllOf(Field(&SourceLocationRef::FileName, "file1"),
diff --git a/llvm/unittests/Support/OptimizedStructLayoutTest.cpp b/llvm/unittests/Support/OptimizedStructLayoutTest.cpp
index 0bcae0dcd5603..92482489f3282 100644
--- a/llvm/unittests/Support/OptimizedStructLayoutTest.cpp
+++ b/llvm/unittests/Support/OptimizedStructLayoutTest.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/OptimizedStructLayout.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -21,14 +22,15 @@ class LayoutTest {
uint64_t ExpectedOffset;
};
- SmallVector<Field, 16> Fields;
- bool Verified = false;
+ llvm::SmallVectorWithFlags<Field, 16> Fields;
+ bool getVerified() const { return Fields.getFlag(0); }
+ void setVerified(bool Value) { Fields.setFlag(0, Value); }
public:
LayoutTest() = default;
LayoutTest(const LayoutTest &) = delete;
LayoutTest &operator=(const LayoutTest &) = delete;
- ~LayoutTest() { assert(Verified); }
+ ~LayoutTest() { assert(getVerified()); }
LayoutTest &flexible(uint64_t Size, uint64_t Alignment,
uint64_t ExpectedOffset) {
@@ -58,7 +60,7 @@ class LayoutTest {
EXPECT_EQ(LF.Offset, F.ExpectedOffset);
}
- Verified = true;
+ setVerified(true);
}
};
diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp
index 78e19c5ff4f2c..ea92431f27199 100644
--- a/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/llvm/unittests/Support/YAMLIOTest.cpp
@@ -3659,3 +3659,36 @@ TYPED_TEST(YAMLIO, FixedSizeArrayMismatch) {
EXPECT_TRUE(!!yin.error());
}
}
+
+TEST(YAMLIO, SmallVectorWithFlagsSequence) {
+ llvm::SmallVectorWithFlags<int, 2, 3> Values;
+ Values.setFlags(5);
+ llvm::SmallVectorWithFlagsImpl<int, 3> &Base = Values;
+ Input In("[1, 2, 3, 4, 5]");
+ In >> Base;
+ EXPECT_FALSE(In.error());
+ EXPECT_THAT(Values, ::testing::ElementsAre(1, 2, 3, 4, 5));
+ EXPECT_EQ(Values.getFlags(), 5u);
+
+ auto Serialize = [](auto &Sequence) {
+ std::string Text;
+ {
+ llvm::raw_string_ostream Stream(Text);
+ Output Out(Stream);
+ Out << Sequence;
+ }
+ return Text;
+ };
+ llvm::SmallVector<int, 2> Plain(Values.begin(), Values.end());
+ EXPECT_EQ(Serialize(Values), Serialize(Plain));
+ EXPECT_EQ(Serialize(Base), Serialize(Plain));
+ EXPECT_EQ(Values.getFlags(), 5u);
+
+ Values.clear();
+ EXPECT_EQ(Values.getFlags(), 5u);
+ Input Replacement("[9]");
+ Replacement >> Values;
+ EXPECT_FALSE(Replacement.error());
+ EXPECT_THAT(Values, ::testing::ElementsAre(9));
+ EXPECT_EQ(Values.getFlags(), 5u);
+}
diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index b756582603ffd..de48d51ccb3a4 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -106,6 +106,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -552,7 +553,8 @@ struct MatchableInfo {
SmallVector<AsmOperand, 8> AsmOperands;
/// Predicates - The required subtarget features to match this instruction.
- SmallVector<const SubtargetFeatureInfo *, 4> RequiredFeatures;
+ llvm::SmallVectorWithFlags<const SubtargetFeatureInfo *, 4, 2>
+ RequiredFeatures;
/// ConversionFnKind - The enum value which is passed to the generated
/// convertToMCInst to convert parsed operands into an MCInst for this
@@ -560,23 +562,34 @@ struct MatchableInfo {
std::string ConversionFnKind;
/// If this instruction is deprecated in some form.
- bool HasDeprecation = false;
+ bool getHasDeprecation() const { return RequiredFeatures.getFlag(0); }
+ bool setHasDeprecation(bool Value) {
+ RequiredFeatures.setFlag(0, Value);
+ return Value;
+ }
/// If this is an alias, this is use to determine whether or not to using
/// the conversion function defined by the instruction's AsmMatchConverter
/// or to use the function generated by the alias.
- bool UseInstAsmMatchConverter;
+ bool getUseInstAsmMatchConverter() const {
+ return RequiredFeatures.getFlag(1);
+ }
+ void setUseInstAsmMatchConverter(bool Value) {
+ RequiredFeatures.setFlag(1, Value);
+ }
MatchableInfo(const CodeGenInstruction &CGI)
: AsmVariantID(0), AsmString(CGI.AsmString), TheDef(CGI.TheDef),
ResInstSize(TheDef->getValueAsInt("Size")), DefRec(&CGI),
- UseInstAsmMatchConverter(true) {}
+ RequiredFeatures(decltype(this->RequiredFeatures)::withFlags(2)) {}
MatchableInfo(std::unique_ptr<const CodeGenInstAlias> Alias)
: AsmVariantID(0), AsmString(Alias->AsmString), TheDef(Alias->TheDef),
ResInstSize(Alias->ResultInst->TheDef->getValueAsInt("Size")),
- DefRec(Alias.release()), UseInstAsmMatchConverter(TheDef->getValueAsBit(
- "UseInstAsmMatchConverter")) {}
+ DefRec(Alias.release()),
+ RequiredFeatures(decltype(this->RequiredFeatures)::withFlags(
+ (unsigned(bool(TheDef->getValueAsBit("UseInstAsmMatchConverter")))
+ << 1))) {}
// Could remove this and the dtor if PointerUnion supported unique_ptr
// elements with a dynamic failure/assertion (like the one below) in the case
@@ -585,10 +598,12 @@ struct MatchableInfo {
: AsmVariantID(RHS.AsmVariantID), AsmString(RHS.AsmString),
TheDef(RHS.TheDef), ResInstSize(RHS.ResInstSize), DefRec(RHS.DefRec),
ResOperands(RHS.ResOperands), Mnemonic(RHS.Mnemonic),
- AsmOperands(RHS.AsmOperands), RequiredFeatures(RHS.RequiredFeatures),
- ConversionFnKind(RHS.ConversionFnKind),
- HasDeprecation(RHS.HasDeprecation),
- UseInstAsmMatchConverter(RHS.UseInstAsmMatchConverter) {
+ AsmOperands(RHS.AsmOperands),
+ RequiredFeatures(decltype(this->RequiredFeatures)::withFlags(
+ unsigned(bool(RHS.getHasDeprecation())) |
+ (unsigned(bool(RHS.getUseInstAsmMatchConverter())) << 1),
+ RHS.RequiredFeatures)),
+ ConversionFnKind(RHS.ConversionFnKind) {
assert(!isa<const CodeGenInstAlias *>(DefRec));
}
@@ -985,8 +1000,8 @@ void MatchableInfo::initialize(
if (!DepMask)
DepMask = TheDef->getValue("ComplexDeprecationPredicate");
- HasDeprecation =
- DepMask ? !DepMask->getValue()->getAsUnquotedString().empty() : false;
+ setHasDeprecation(
+ DepMask ? !DepMask->getValue()->getAsUnquotedString().empty() : false);
}
/// Append an AsmOperand for the given substring of AsmString.
@@ -2140,7 +2155,7 @@ emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
// Check if we have a custom match function.
StringRef AsmMatchConverter =
II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
- if (!AsmMatchConverter.empty() && II->UseInstAsmMatchConverter) {
+ if (!AsmMatchConverter.empty() && II->getUseInstAsmMatchConverter()) {
std::string Signature = ("ConvertCustom_" + AsmMatchConverter).str();
II->ConversionFnKind = Signature;
@@ -3767,7 +3782,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
bool HasDeprecation = false;
for (const auto &MI : Info.Matchables) {
MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size());
- HasDeprecation |= MI->HasDeprecation;
+ HasDeprecation |= MI->getHasDeprecation();
// Store a pascal-style length byte in the mnemonic.
std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.lower();
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index b497c4dcd7806..6e96d17c74402 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -512,7 +512,7 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
else if (R->getName() == "IntrNoMerge")
isNoMerge = true;
else if (R->getName() == "IntrConvergent")
- isConvergent = true;
+ setIsConvergent(true);
else if (R->getName() == "IntrNoReturn")
isNoReturn = true;
else if (R->getName() == "IntrNoCallback")
@@ -520,21 +520,21 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
else if (R->getName() == "IntrNoSync")
isNoSync = true;
else if (R->getName() == "IntrNoFree")
- isNoFree = true;
+ setIsNoFree(true);
else if (R->getName() == "IntrWillReturn")
- isWillReturn = !isNoReturn;
+ setIsWillReturn(!isNoReturn);
else if (R->getName() == "IntrCold")
- isCold = true;
+ setIsCold(true);
else if (R->getName() == "IntrSpeculatable")
- isSpeculatable = true;
+ setIsSpeculatable(true);
else if (R->getName() == "IntrHasSideEffects")
- hasSideEffects = true;
+ setHasSideEffects(true);
else if (R->getName() == "IntrStrictFP")
- isStrictFP = true;
+ setIsStrictFP(true);
else if (R->getName() == "IntrNoCreateUndefOrPoison")
- isNoCreateUndefOrPoison = true;
+ setIsNoCreateUndefOrPoison(true);
else if (R->getName() == "IntrTriviallyScalarizable")
- isTriviallyScalarizable = true;
+ setIsTriviallyScalarizable(true);
else if (R->isSubClassOf("NoCapture")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
addArgAttribute(ArgNo, NoCapture);
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
index bd8a35dfc4de8..d265745fb7af8 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/ModRef.h"
#include <string>
#include <tuple>
@@ -94,32 +95,70 @@ struct CodeGenIntrinsic {
bool isNoSync = false;
/// True if the intrinsic is no-free.
- bool isNoFree = false;
+ bool getIsNoFree() const { return ParamDefaultValues.getFlag(0); }
+ bool setIsNoFree(bool Value) {
+ ParamDefaultValues.setFlag(0, Value);
+ return Value;
+ }
/// True if the intrinsic is will-return.
- bool isWillReturn = false;
+ bool getIsWillReturn() const { return ParamDefaultValues.getFlag(1); }
+ bool setIsWillReturn(bool Value) {
+ ParamDefaultValues.setFlag(1, Value);
+ return Value;
+ }
/// True if the intrinsic is cold.
- bool isCold = false;
+ bool getIsCold() const { return ParamDefaultValues.getFlag(2); }
+ bool setIsCold(bool Value) {
+ ParamDefaultValues.setFlag(2, Value);
+ return Value;
+ }
/// True if the intrinsic is marked as convergent.
- bool isConvergent = false;
+ bool getIsConvergent() const { return ParamDefaultValues.getFlag(3); }
+ bool setIsConvergent(bool Value) {
+ ParamDefaultValues.setFlag(3, Value);
+ return Value;
+ }
/// True if the intrinsic has side effects that aren't captured by any
/// of the other flags.
- bool hasSideEffects = false;
+ bool getHasSideEffects() const { return PrettyPrintFunctions.getFlag(0); }
+ bool setHasSideEffects(bool Value) {
+ PrettyPrintFunctions.setFlag(0, Value);
+ return Value;
+ }
// True if the intrinsic is marked as speculatable.
- bool isSpeculatable = false;
+ bool getIsSpeculatable() const { return PrettyPrintFunctions.getFlag(1); }
+ bool setIsSpeculatable(bool Value) {
+ PrettyPrintFunctions.setFlag(1, Value);
+ return Value;
+ }
// True if the intrinsic is marked as strictfp.
- bool isStrictFP = false;
+ bool getIsStrictFP() const { return PrettyPrintFunctions.getFlag(2); }
+ bool setIsStrictFP(bool Value) {
+ PrettyPrintFunctions.setFlag(2, Value);
+ return Value;
+ }
// True if the intrinsic is marked as IntrNoCreateUndefOrPoison.
- bool isNoCreateUndefOrPoison = false;
+ bool getIsNoCreateUndefOrPoison() const {
+ return PrettyPrintFunctions.getFlag(3);
+ }
+ bool setIsNoCreateUndefOrPoison(bool Value) {
+ PrettyPrintFunctions.setFlag(3, Value);
+ return Value;
+ }
// True if the intrinsic is marked as IntrTriviallyScalarizable.
- bool isTriviallyScalarizable = false;
+ bool getIsTriviallyScalarizable() const { return ImmArgRangeSets.getFlag(0); }
+ bool setIsTriviallyScalarizable(bool Value) {
+ ImmArgRangeSets.setFlag(0, Value);
+ return Value;
+ }
enum ArgAttrKind {
NoCapture,
@@ -163,7 +202,7 @@ struct CodeGenIntrinsic {
SmallVector<SmallVector<ArgAttribute, 0>> ArgumentAttributes;
/// Range-set constraints for immediate arguments, indexed by argument number.
- SmallVector<ImmArgRangeSet> ImmArgRangeSets;
+ llvm::SmallVectorWithFlags<ImmArgRangeSet> ImmArgRangeSets;
void addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V = 0,
uint64_t V2 = 0);
@@ -180,10 +219,18 @@ struct CodeGenIntrinsic {
};
/// Vector that stores ArgInfo (ArgIndex, ArgName, FunctionName).
- SmallVector<PrettyPrintArgInfo> PrettyPrintFunctions;
+ llvm::SmallVectorWithFlags<PrettyPrintArgInfo,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ PrettyPrintArgInfo>::value,
+ 4>
+ PrettyPrintFunctions;
/// Default values for parameters. Index = param index.
- SmallVector<std::optional<uint64_t>> ParamDefaultValues;
+ llvm::SmallVectorWithFlags<std::optional<uint64_t>,
+ llvm::CalculateSmallVectorDefaultInlinedElements<
+ std::optional<uint64_t>>::value,
+ 4>
+ ParamDefaultValues;
void addPrettyPrintFunction(unsigned ArgIdx, StringRef ArgName,
StringRef FuncName);
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index 61a4aa31aa222..5a9c3885c31ff 100644
--- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
@@ -367,10 +367,11 @@ void IntrinsicEmitter::EmitIntrinsicToOverloadTable(
void IntrinsicEmitter::EmitIntrinsicToScalarizableTable(
const CodeGenIntrinsicTable &Ints, raw_ostream &OS) {
- EmitIntrinsicBitTable(
- Ints, OS, "GET_INTRINSIC_SCALARIZABLE_TABLE", "STable",
- "Intrinsic ID to trivially scalarizable bitset.",
- [](const CodeGenIntrinsic &Int) { return Int.isTriviallyScalarizable; });
+ EmitIntrinsicBitTable(Ints, OS, "GET_INTRINSIC_SCALARIZABLE_TABLE", "STable",
+ "Intrinsic ID to trivially scalarizable bitset.",
+ [](const CodeGenIntrinsic &Int) {
+ return Int.getIsTriviallyScalarizable();
+ });
}
using TypeSigTy = SmallVector<unsigned char>;
@@ -497,7 +498,7 @@ static constexpr FixedEncodingTy IIT_Table[] = {{
static MemoryEffects getEffectiveME(const CodeGenIntrinsic &Int) {
MemoryEffects ME = Int.ME;
// TODO: IntrHasSideEffects should affect not only readnone intrinsics.
- if (ME.doesNotAccessMemory() && Int.hasSideEffects)
+ if (ME.doesNotAccessMemory() && Int.getHasSideEffects())
ME = MemoryEffects::unknown();
return ME;
}
@@ -506,11 +507,12 @@ static bool compareFnAttributes(const CodeGenIntrinsic *L,
const CodeGenIntrinsic *R) {
auto TieBoolAttributes = [](const CodeGenIntrinsic *I) -> auto {
// Sort throwing intrinsics after non-throwing intrinsics.
- return std::tie(I->canThrow, I->isNoDuplicate, I->isNoMerge, I->isNoReturn,
- I->isNoCallback, I->isNoSync, I->isNoFree, I->isWillReturn,
- I->isCold, I->isConvergent, I->isSpeculatable,
- I->hasSideEffects, I->isStrictFP,
- I->isNoCreateUndefOrPoison);
+ return std::make_tuple(I->canThrow, I->isNoDuplicate, I->isNoMerge,
+ I->isNoReturn, I->isNoCallback, I->isNoSync,
+ I->getIsNoFree(), I->getIsWillReturn(),
+ I->getIsCold(), I->getIsConvergent(),
+ I->getIsSpeculatable(), I->getHasSideEffects(),
+ I->getIsStrictFP(), I->getIsNoCreateUndefOrPoison());
};
auto TieL = TieBoolAttributes(L);
@@ -533,9 +535,10 @@ static bool compareFnAttributes(const CodeGenIntrinsic *L,
// intrinsic has NoUnwind attribute.
static bool hasFnAttributes(const CodeGenIntrinsic &Int) {
return !Int.canThrow || Int.isNoReturn || Int.isNoCallback || Int.isNoSync ||
- Int.isNoFree || Int.isWillReturn || Int.isCold || Int.isNoDuplicate ||
- Int.isNoMerge || Int.isConvergent || Int.isSpeculatable ||
- Int.isStrictFP || Int.isNoCreateUndefOrPoison ||
+ Int.getIsNoFree() || Int.getIsWillReturn() || Int.getIsCold() ||
+ Int.isNoDuplicate || Int.isNoMerge || Int.getIsConvergent() ||
+ Int.getIsSpeculatable() || Int.getIsStrictFP() ||
+ Int.getIsNoCreateUndefOrPoison() ||
getEffectiveME(Int) != MemoryEffects::unknown();
}
@@ -681,23 +684,23 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
addAttribute("NoCallback");
if (Int.isNoSync)
addAttribute("NoSync");
- if (Int.isNoFree)
+ if (Int.getIsNoFree())
addAttribute("NoFree");
- if (Int.isWillReturn)
+ if (Int.getIsWillReturn())
addAttribute("WillReturn");
- if (Int.isCold)
+ if (Int.getIsCold())
addAttribute("Cold");
if (Int.isNoDuplicate)
addAttribute("NoDuplicate");
if (Int.isNoMerge)
addAttribute("NoMerge");
- if (Int.isConvergent)
+ if (Int.getIsConvergent())
addAttribute("Convergent");
- if (Int.isSpeculatable)
+ if (Int.getIsSpeculatable())
addAttribute("Speculatable");
- if (Int.isStrictFP)
+ if (Int.getIsStrictFP())
addAttribute("StrictFP");
- if (Int.isNoCreateUndefOrPoison)
+ if (Int.getIsNoCreateUndefOrPoison())
addAttribute("NoCreateUndefOrPoison");
const MemoryEffects ME = getEffectiveME(Int);
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index d3b7a1af36195..b55c600b0a2db 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -3189,7 +3189,7 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
// chain.
if (Int.IS.RetTys.empty())
Operator = getDAGPatterns().get_intrinsic_void_sdnode();
- else if (!Int.ME.doesNotAccessMemory() || Int.hasSideEffects)
+ else if (!Int.ME.doesNotAccessMemory() || Int.getHasSideEffects())
// Has side-effects, requires chain.
Operator = getDAGPatterns().get_intrinsic_w_chain_sdnode();
else // Otherwise, no chain.
@@ -3829,7 +3829,8 @@ class InstAnalyzer {
// Consider intrinsics that don't specify any restrictions on memory
// effects as having a side-effect.
- if (IntInfo->ME == MemoryEffects::unknown() || IntInfo->hasSideEffects)
+ if (IntInfo->ME == MemoryEffects::unknown() ||
+ IntInfo->getHasSideEffects())
hasSideEffects = true;
}
}
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index 500b6e21293f1..bc5e33b8a2a12 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -54,7 +54,7 @@ using namespace llvm;
CodeGenSubRegIndex::CodeGenSubRegIndex(const Record *R, unsigned Enum,
const CodeGenHwModes &CGH)
: TheDef(R), Name(R->getName().str()), EnumValue(Enum),
- AllSuperRegsCovered(true), Artificial(true) {
+ ConcatenationOf(decltype(this->ConcatenationOf)::withFlags(3)) {
if (R->getValue("Namespace"))
Namespace = R->getValueAsString("Namespace").str();
@@ -67,8 +67,8 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(const Record *R, unsigned Enum,
CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace,
unsigned Enum)
: TheDef(nullptr), Name(N.str()), Namespace(Nspace.str()),
- Range(SubRegRange(-1, -1)), EnumValue(Enum), AllSuperRegsCovered(true),
- Artificial(true) {}
+ Range(SubRegRange(-1, -1)), EnumValue(Enum),
+ ConcatenationOf(decltype(this->ConcatenationOf)::withFlags(3)) {}
std::string CodeGenSubRegIndex::getQualifiedName() const {
std::string N = getNamespace();
@@ -163,11 +163,11 @@ void CodeGenSubRegIndex::computeConcatTransitiveClosure() {
CodeGenRegister::CodeGenRegister(const Record *R, unsigned Enum)
: TheDef(R), EnumValue(Enum),
- CostPerUse(R->getValueAsListOfInts("CostPerUse")),
- CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")),
- Constant(R->getValueAsBit("isConstant")), SubRegsComplete(false),
- SuperRegsComplete(false), TopoSig(~0u) {
- Artificial = R->getValueAsBit("isArtificial");
+ CostPerUse(R->getValueAsListOfInts("CostPerUse")), TopoSig(~0u),
+ RegUnitLaneMasks(decltype(this->RegUnitLaneMasks)::withFlags(
+ unsigned(!(bool(R->getValueAsBit("CoveredBySubRegs")))) |
+ (unsigned(bool(R->getValueAsBit("isConstant"))) << 3))) {
+ setArtificial(R->getValueAsBit("isArtificial"));
}
void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) {
@@ -185,7 +185,7 @@ void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) {
// sub-register.
//
// This is used by computeSecondarySubRegs() to find candidates.
- if (CoveredBySubRegs && !ExplicitSubRegs.empty())
+ if (getCoveredBySubRegs() && !ExplicitSubRegs.empty())
ExplicitSubRegs.front()->LeadingSuperRegs.push_back(this);
// Add ad hoc alias links. This is a symmetric relationship between two
@@ -212,16 +212,16 @@ bool CodeGenRegister::inheritRegUnits(CodeGenRegBank &RegBank) {
const CodeGenRegister::SubRegMap &
CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
// Only compute this map once.
- if (SubRegsComplete)
+ if (getSubRegsComplete())
return SubRegs;
- SubRegsComplete = true;
+ setSubRegsComplete(true);
- HasDisjunctSubRegs = ExplicitSubRegs.size() > 1;
+ setHasDisjunctSubRegs(ExplicitSubRegs.size() > 1);
// First insert the explicit subregs and make sure they are fully indexed.
for (auto [SR, Idx] : zip_equal(ExplicitSubRegs, ExplicitSubRegIndices)) {
- if (!SR->Artificial)
- Idx->Artificial = false;
+ if (!SR->getArtificial())
+ Idx->setArtificial(false);
if (!SubRegs.try_emplace(Idx, SR).second)
PrintFatalError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
" appears twice in Register " +
@@ -238,7 +238,8 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
// Here the order is important - earlier subregs take precedence.
for (CodeGenRegister *ESR : ExplicitSubRegs) {
const SubRegMap &Map = ESR->computeSubRegs(RegBank);
- HasDisjunctSubRegs |= ESR->HasDisjunctSubRegs;
+ setHasDisjunctSubRegs(int(getHasDisjunctSubRegs()) |
+ (ESR->getHasDisjunctSubRegs()));
for (const auto &SR : Map) {
if (!SubRegs.insert(SR).second)
@@ -309,8 +310,8 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
}
// Compute AllSuperRegsCovered.
- if (!CoveredBySubRegs)
- SRI->AllSuperRegsCovered = false;
+ if (!getCoveredBySubRegs())
+ SRI->setAllSuperRegsCovered(false);
// Ensure that every sub-register has a unique name.
DenseMap<const CodeGenRegister *, CodeGenSubRegIndex *>::iterator Ins =
@@ -331,7 +332,7 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
// that getConcatSubRegIndex() won't invent any concatenated indices that the
// user already specified.
for (auto [Idx, SR] : enumerate(ExplicitSubRegs)) {
- if (!SR->CoveredBySubRegs || SR->Artificial)
+ if (!SR->getCoveredBySubRegs() || SR->getArtificial())
continue;
// SR is composed of multiple sub-regs. Find their names in this register.
@@ -339,7 +340,7 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
SmallVector<CodeGenSubRegIndex *, 8> Parts;
for (unsigned j = 0, e = SR->ExplicitSubRegs.size(); j != e; ++j) {
CodeGenSubRegIndex &I = *SR->ExplicitSubRegIndices[j];
- if (I.Artificial) {
+ if (I.getArtificial()) {
AnyArtificial = true;
break;
}
@@ -373,7 +374,7 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
// the added complexity.
for (CodeGenRegister *AR : ExplicitAliases) {
// Only visit each edge once.
- if (AR->SubRegsComplete)
+ if (AR->getSubRegsComplete())
continue;
// Create a RegUnit representing this alias edge, and add it to both
// registers.
@@ -404,7 +405,7 @@ void CodeGenRegister::checkSubRegIndexSizes(CodeGenRegBank &RegBank) const {
// tiled by them; for those an explicit SubRegIndex extending past the
// register is a genuine bug. A register that is not covered by its
// sub-registers makes no such promise, so don't second-guess its layout.
- if (!CoveredBySubRegs)
+ if (!getCoveredBySubRegs())
return;
// This register's own bit size is the largest register class containing it.
@@ -553,9 +554,9 @@ void CodeGenRegister::computeSecondarySubRegs(CodeGenRegBank &RegBank) {
void CodeGenRegister::computeSuperRegs(CodeGenRegBank &RegBank) {
// Only visit each register once.
- if (SuperRegsComplete)
+ if (getSuperRegsComplete())
return;
- SuperRegsComplete = true;
+ setSuperRegsComplete(true);
// Make sure all sub-registers have been visited first, so the super-reg
// lists will be topologically ordered.
@@ -582,7 +583,7 @@ void CodeGenRegister::computeSuperRegs(CodeGenRegBank &RegBank) {
void CodeGenRegister::addSubRegsPreOrder(
SetVector<const CodeGenRegister *> &OSet, CodeGenRegBank &RegBank) const {
- assert(SubRegsComplete && "Must precompute sub-registers");
+ assert(getSubRegsComplete() && "Must precompute sub-registers");
for (CodeGenRegister *SR : ExplicitSubRegs) {
if (OSet.insert(SR))
SR->addSubRegsPreOrder(OSet, RegBank);
@@ -748,7 +749,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
: TheDef(R), Name(R->getName().str()),
RegsWithSuperRegsTopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1),
TSFlags(0) {
- GeneratePressureSet = R->getValueAsBit("GeneratePressureSet");
+ setGeneratePressureSet(R->getValueAsBit("GeneratePressureSet"));
for (const Record *Type : R->getValueAsListOfDefs("RegTypes"))
VTs.push_back(getValueTypeByHwMode(Type, RegBank.getHwModes()));
@@ -759,13 +760,13 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
// Default allocation order always contains all registers.
MemberBV.resize(RegBank.getRegisters().size());
- Artificial = true;
+ setArtificial(true);
for (const Record *Element : *Elements) {
Orders[0].push_back(Element);
const CodeGenRegister *Reg = RegBank.getReg(Element);
Members.push_back(Reg);
MemberBV.set(CodeGenRegBank::getRegIndex(Reg));
- Artificial &= Reg->Artificial;
+ setArtificial(int(getArtificial()) & (Reg->getArtificial()));
if (!Reg->getSuperRegs().empty())
RegsWithSuperRegsTopoSigs.set(Reg->getTopoSig());
}
@@ -802,7 +803,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
}
int CopyCostParsed = R->getValueAsInt("CopyCost");
- Allocatable = R->getValueAsBit("isAllocatable");
+ setAllocatable(R->getValueAsBit("isAllocatable"));
AltOrderSelect = R->getValueAsString("AltOrderSelect");
int SpillStackIDParsed = R->getValueAsInt("SpillStackID");
if (!isUInt<8>(SpillStackIDParsed))
@@ -813,7 +814,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
PrintFatalError(R->getLoc(), "AllocationPriority out of range [0,31]");
this->AllocationPriority = AllocationPriority;
- GlobalPriority = R->getValueAsBit("GlobalPriority");
+ setGlobalPriority(R->getValueAsBit("GlobalPriority"));
const BitsInit *TSF = R->getValueAsBitsInit("TSFlags");
TSFlags = uint8_t(*TSF->convertInitializerToInt());
@@ -834,16 +835,16 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
StringRef Name, Key Props)
: Members(*Props.Members), TheDef(nullptr), Name(Name.str()),
RegsWithSuperRegsTopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1),
- RSI(Props.RSI), CopyCost(0), Allocatable(true), AllocationPriority(0),
- GlobalPriority(false), TSFlags(0), SpillStackID(0) {
+ VTs(decltype(this->VTs)::withFlags(1)), RSI(Props.RSI), CopyCost(0),
+ AllocationPriority(0), TSFlags(0), SpillStackID(0) {
MemberBV.resize(RegBank.getRegisters().size());
- Artificial = true;
- GeneratePressureSet = false;
+ setArtificial(true);
+ setGeneratePressureSet(false);
for (const auto R : Members) {
MemberBV.set(CodeGenRegBank::getRegIndex(R));
if (!R->getSuperRegs().empty())
RegsWithSuperRegsTopoSigs.set(R->getTopoSig());
- Artificial &= R->Artificial;
+ setArtificial(int(getArtificial()) & (R->getArtificial()));
}
}
@@ -856,8 +857,9 @@ void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
// allocatable super-classes and inherit from the nearest allocatable one if
// any.
auto NearestAllocSCRIt =
- find_if(reverse(SuperClasses),
- [&](const CodeGenRegisterClass *S) { return S->Allocatable; });
+ find_if(reverse(SuperClasses), [&](const CodeGenRegisterClass *S) {
+ return S->getAllocatable();
+ });
CodeGenRegisterClass &Super = NearestAllocSCRIt == SuperClasses.rend()
? *SuperClasses.back()
: **NearestAllocSCRIt;
@@ -865,15 +867,17 @@ void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
// Most properties are copied directly.
// Exceptions are members, size, and alignment
Namespace = Super.Namespace;
- VTs = Super.VTs;
+ if (VTs.data() != Super.VTs.data())
+ VTs.assign(Super.VTs.begin(), Super.VTs.end());
CopyCost = Super.CopyCost;
- Allocatable = Super.Allocatable;
+ setAllocatable(Super.getAllocatable());
AltOrderSelect = Super.AltOrderSelect;
AllocationPriority = Super.AllocationPriority;
- GlobalPriority = Super.GlobalPriority;
+ setGlobalPriority(Super.getGlobalPriority());
TSFlags = Super.TSFlags;
SpillStackID = Super.SpillStackID;
- GeneratePressureSet |= Super.GeneratePressureSet;
+ setGeneratePressureSet(int(getGeneratePressureSet()) |
+ (Super.getGeneratePressureSet()));
// Copy all allocation orders, filter out foreign registers from the larger
// super-class.
@@ -912,11 +916,11 @@ unsigned CodeGenRegisterClass::getWeight(const CodeGenRegBank &RegBank) const {
if (TheDef && !TheDef->isValueUnset("Weight"))
return TheDef->getValueAsInt("Weight");
- if (Artificial)
+ if (getArtificial())
return 0;
for (const CodeGenRegister *Reg : Members) {
- if (!Reg->Artificial)
+ if (!Reg->getArtificial())
return Reg->getWeight(RegBank);
}
@@ -933,9 +937,9 @@ bool CodeGenRegisterClass::Key::operator<(
auto IA = Members->begin(), EA = Members->end();
auto IB = B.Members->begin(), EB = B.Members->end();
for (;;) {
- while (IgnoreArtificialMembers && IA != EA && (*IA)->Artificial)
+ while (IgnoreArtificialMembers && IA != EA && (*IA)->getArtificial())
++IA;
- while (IgnoreArtificialMembers && IB != EB && (*IB)->Artificial)
+ while (IgnoreArtificialMembers && IB != EB && (*IB)->getArtificial())
++IB;
if (IA == EA && IB == EB)
break;
@@ -1019,7 +1023,7 @@ void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
CodeGenRegisterClass &RC = *I;
RC.SubClasses.resize(NumRegClasses);
RC.SubClasses.set(RC.EnumValue);
- if (RC.Artificial)
+ if (RC.getArtificial())
continue;
// Normally, all subclasses have IDs >= rci, unless RC is part of a clique.
@@ -1223,7 +1227,8 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
const CodeGenHwModes &Modes,
const bool RegistersAreIntervals)
: Records(Records), CGH(Modes),
- RegistersAreIntervals(RegistersAreIntervals) {
+ RegUnits(decltype(this->RegUnits)::withFlags(
+ unsigned(RegistersAreIntervals))) {
// Configure register Sets to understand register classes and tuples.
Sets.addFieldExpander("RegisterClass", "MemberList");
Sets.addFieldExpander("CalleeSavedRegs", "SaveList");
@@ -1303,7 +1308,7 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
// Infer even more sub-registers by combining leading super-registers.
for (CodeGenRegister &Reg : Registers)
- if (Reg.CoveredBySubRegs)
+ if (Reg.getCoveredBySubRegs())
Reg.computeSecondarySubRegs(*this);
// After the sub-register graph is complete, compute the topologically
@@ -1314,11 +1319,11 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
// For each pair of Reg:SR, if both are non-artificial, mark the
// corresponding sub-register index as non-artificial.
for (CodeGenRegister &Reg : Registers) {
- if (Reg.Artificial)
+ if (Reg.getArtificial())
continue;
for (auto [SRI, SR] : Reg.getSubRegs()) {
- if (!SR->Artificial)
- SRI->Artificial = false;
+ if (!SR->getArtificial())
+ SRI->setArtificial(false);
}
}
@@ -1339,7 +1344,7 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
RegClasses.emplace_back(*this, R);
CodeGenRegisterClass &RC = RegClasses.back();
RegClassNames.insert(RC.getName());
- if (!RC.Artificial)
+ if (!RC.getArtificial())
addToMaps(&RC);
}
@@ -1708,7 +1713,7 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
LaneBitmask Mask = Idx.computeLaneMask();
// If some super-registers without CoveredBySubRegs use this index, we can
// no longer assume that the lanes are covering their registers.
- if (!Idx.AllSuperRegsCovered)
+ if (!Idx.getAllSuperRegsCovered())
CoveringLanes &= ~Mask;
}
@@ -1849,7 +1854,7 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets,
IntEqClasses UberSetIDs(Registers.size() + 1);
BitVector AllocatableRegs(Registers.size() + 1);
for (CodeGenRegisterClass &RegClass : RegBank.getRegClasses()) {
- if (!RegClass.Allocatable)
+ if (!RegClass.getAllocatable())
continue;
// Ignore artificial registers. They may be members of register
@@ -1858,7 +1863,7 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets,
// their register units.
CodeGenRegister::Vec Regs;
for (const CodeGenRegister *Reg : RegClass.getMembers()) {
- if (!Reg->Artificial)
+ if (!Reg->getArtificial())
Regs.push_back(Reg);
}
@@ -2059,7 +2064,7 @@ static bool isContiguous(const CodeGenRegister::RegUnitList &Units) {
// requests this property. This will renumber regunits to ensure the
// interval property holds, or error out if it cannot be satisfied.
void CodeGenRegBank::enforceRegUnitIntervals() {
- if (!RegistersAreIntervals)
+ if (!getRegistersAreIntervals())
return;
LLVM_DEBUG(dbgs() << "Enforcing regunit intervals for target\n");
@@ -2232,7 +2237,8 @@ void CodeGenRegBank::computeRegUnitSets() {
// Compute a unique RegUnitSet for each RegClass.
auto &RegClasses = getRegClasses();
for (CodeGenRegisterClass &RC : RegClasses) {
- if (!RC.Allocatable || RC.Artificial || !RC.GeneratePressureSet)
+ if (!RC.getAllocatable() || RC.getArtificial() ||
+ !RC.getGeneratePressureSet())
continue;
// Compute a sorted list of units in this class.
@@ -2313,7 +2319,7 @@ void CodeGenRegBank::computeRegUnitSets() {
// For each register class, list the UnitSets that are supersets.
RegClassUnitSets.resize(RegClasses.size());
for (CodeGenRegisterClass &RC : RegClasses) {
- if (!RC.Allocatable)
+ if (!RC.getAllocatable())
continue;
// Recompute the sorted list of units in this class.
@@ -2338,9 +2344,9 @@ void CodeGenRegBank::computeRegUnitSets() {
}
}
LLVM_DEBUG(dbgs() << '\n');
- assert(
- (!RegClassUnitSets[RC.EnumValue].empty() || !RC.GeneratePressureSet) &&
- "missing unit set for regclass");
+ assert((!RegClassUnitSets[RC.EnumValue].empty() ||
+ !RC.getGeneratePressureSet()) &&
+ "missing unit set for regclass");
}
// For each register unit, ensure that we have the list of UnitSets that
@@ -2407,7 +2413,7 @@ void CodeGenRegBank::computeRegUnitLaneMasks() {
// interference and liveness queries. Backfill the missing lanes onto the
// sub-register's own native units.
for (auto [SubRegIndex, SubReg] : SubRegs) {
- if (SubReg->CoveredBySubRegs || SubReg->getSubRegs().empty())
+ if (SubReg->getCoveredBySubRegs() || SubReg->getSubRegs().empty())
continue;
LaneBitmask Unclaimed = SubRegIndex->LaneMask;
for (unsigned SUI : SubReg->getNativeRegUnits())
@@ -2443,11 +2449,13 @@ void CodeGenRegBank::computeDerivedInfo() {
// Compute register class HasDisjunctSubRegs/CoveredBySubRegs flag.
for (CodeGenRegisterClass &RC : RegClasses) {
- RC.HasDisjunctSubRegs = false;
- RC.CoveredBySubRegs = true;
+ RC.setHasDisjunctSubRegs(false);
+ RC.setCoveredBySubRegs(true);
for (const CodeGenRegister *Reg : RC.getMembers()) {
- RC.HasDisjunctSubRegs |= Reg->HasDisjunctSubRegs;
- RC.CoveredBySubRegs &= Reg->CoveredBySubRegs;
+ RC.setHasDisjunctSubRegs(int(RC.getHasDisjunctSubRegs()) |
+ (Reg->getHasDisjunctSubRegs()));
+ RC.setCoveredBySubRegs(int(RC.getCoveredBySubRegs()) &
+ (Reg->getCoveredBySubRegs()));
}
}
@@ -2501,7 +2509,7 @@ void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
// Skip casses where the intersection is composed of artificial
// registers.
if (llvm::all_of(Intersection, [](const CodeGenRegister *Reg) {
- return Reg->Artificial;
+ return Reg->getArtificial();
}))
continue;
@@ -2529,7 +2537,7 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
// Compute the set of registers supporting each SubRegIndex.
SubReg2SetMap SRSets;
for (const CodeGenRegister *R : RC->getMembers()) {
- if (R->Artificial)
+ if (R->getArtificial())
continue;
const CodeGenRegister::SubRegMap &SRM = R->getSubRegs();
for (auto [I, _] : SRM)
@@ -2545,14 +2553,14 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
continue;
// In most cases, all RC registers support the SubRegIndex.
auto IsNotArtificial = [](const CodeGenRegister *R) {
- return !R->Artificial;
+ return !R->getArtificial();
};
if (I->second.size() ==
(size_t)count_if(RC->getMembers(), IsNotArtificial)) {
RC->setSubClassWithSubReg(&SubIdx, RC);
continue;
}
- if (SubIdx.Artificial)
+ if (SubIdx.getArtificial())
continue;
// This is a real subset. See if we have a matching class.
CodeGenRegisterClass *SubRC =
@@ -2595,7 +2603,7 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
SubRegs.clear();
TopoSigs.reset();
for (const CodeGenRegister *Super : RC->getMembers()) {
- if (Super->Artificial)
+ if (Super->getArtificial())
continue;
const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second;
assert(Sub && "Missing sub-register");
@@ -2611,7 +2619,7 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
for (auto I = FirstSubRegRC, E = std::prev(RegClasses.end());
I != std::next(E); ++I) {
CodeGenRegisterClass &SubRC = *I;
- if (SubRC.Artificial)
+ if (SubRC.getArtificial())
continue;
// Topological shortcut: SubRC members have the wrong shape.
if (!TopoSigs.anyCommon(SubRC.getRegsWithSuperRegsTopoSigs()))
@@ -2619,7 +2627,7 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
// Compute the subset of RC that maps into SubRC.
CodeGenRegister::Vec SubSetVec;
auto IsNotArtificial = [](const CodeGenRegister *R) {
- return !R->Artificial;
+ return !R->getArtificial();
};
auto NonArtificialMembers =
make_filter_range(RC->getMembers(), IsNotArtificial);
@@ -2713,7 +2721,7 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
// Watch out for iterator invalidation here.
for (auto I = RegClasses.begin(), E = RegClasses.end(); I != E; ++I) {
CodeGenRegisterClass *RC = &*I;
- if (RC->Artificial)
+ if (RC->getArtificial())
continue;
// Synthesize answers for getSubClassWithSubReg().
@@ -2868,7 +2876,7 @@ CodeGenRegBank::getSuperRegForSubReg(const ValueTypeByHwMode &ValueTy,
continue;
// If necessary, check that it is allocatable.
- if (MustBeAllocatable && !SubClassWithSubReg->Allocatable)
+ if (MustBeAllocatable && !SubClassWithSubReg->getAllocatable())
continue;
// We have a register class which supports both the value type and
@@ -2912,7 +2920,7 @@ CodeGenRegBank::computeCoveredRegisters(ArrayRef<const Record *> Regs) {
// Second, find all super-registers that are completely covered by the set.
for (unsigned i = 0; i != Set.size(); ++i) {
for (const CodeGenRegister *Super : Set[i]->getSuperRegs()) {
- if (!Super->CoveredBySubRegs || Set.contains(Super))
+ if (!Super->getCoveredBySubRegs() || Set.contains(Super))
continue;
// This new super-register is covered by its sub-registers.
bool AllSubsInSet = true;
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h
index a37028714306e..e4d533c342e09 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h
@@ -22,6 +22,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -75,15 +76,23 @@ class CodeGenSubRegIndex {
/// A list of subregister indexes concatenated resulting in this
/// subregister index. This is the reverse of CodeGenRegBank::ConcatIdx.
- SmallVector<CodeGenSubRegIndex *, 4> ConcatenationOf;
+ llvm::SmallVectorWithFlags<CodeGenSubRegIndex *, 4, 2> ConcatenationOf;
// Are all super-registers containing this SubRegIndex covered by their
// sub-registers?
- bool AllSuperRegsCovered;
+ bool getAllSuperRegsCovered() const { return ConcatenationOf.getFlag(0); }
+ bool setAllSuperRegsCovered(bool Value) {
+ ConcatenationOf.setFlag(0, Value);
+ return Value;
+ }
// A subregister index is "artificial" if every subregister obtained
// from applying this index is artificial. Artificial subregister
// indexes are not used to create new register classes.
- bool Artificial;
+ bool getArtificial() const { return ConcatenationOf.getFlag(1); }
+ bool setArtificial(bool Value) {
+ ConcatenationOf.setFlag(1, Value);
+ return Value;
+ }
CodeGenSubRegIndex(const Record *R, unsigned Enum, const CodeGenHwModes &CGH);
CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
@@ -176,10 +185,14 @@ class CodeGenRegister {
const Record *TheDef;
unsigned EnumValue;
std::vector<int64_t> CostPerUse;
- bool CoveredBySubRegs = true;
- bool HasDisjunctSubRegs = false;
- bool Artificial = true;
- bool Constant = false;
+ bool getCoveredBySubRegs() const { return !RegUnitLaneMasks.getFlag(0); }
+ void setCoveredBySubRegs(bool Value) { RegUnitLaneMasks.setFlag(0, !Value); }
+ bool getHasDisjunctSubRegs() const { return RegUnitLaneMasks.getFlag(1); }
+ void setHasDisjunctSubRegs(bool Value) { RegUnitLaneMasks.setFlag(1, Value); }
+ bool getArtificial() const { return !RegUnitLaneMasks.getFlag(2); }
+ void setArtificial(bool Value) { RegUnitLaneMasks.setFlag(2, !Value); }
+ bool getConstant() const { return RegUnitLaneMasks.getFlag(3); }
+ void setConstant(bool Value) { RegUnitLaneMasks.setFlag(3, Value); }
// Map SubRegIndex -> Register.
using SubRegMap =
@@ -213,7 +226,7 @@ class CodeGenRegister {
void checkSubRegIndexSizes(CodeGenRegBank &) const;
const SubRegMap &getSubRegs() const {
- assert(SubRegsComplete && "Must precompute sub-registers");
+ assert(getSubRegsComplete() && "Must precompute sub-registers");
return SubRegs;
}
@@ -233,7 +246,7 @@ class CodeGenRegister {
// This is valid after computeSubRegs visits all registers during RegBank
// construction.
const SuperRegList &getSuperRegs() const {
- assert(SubRegsComplete && "Must precompute sub-registers");
+ assert(getSubRegsComplete() && "Must precompute sub-registers");
return SuperRegs;
}
@@ -250,7 +263,7 @@ class CodeGenRegister {
// sub-register indices mapping to the same kind of sub-registers
// (TopoSig-wise).
unsigned getTopoSig() const {
- assert(SuperRegsComplete && "TopoSigs haven't been computed yet.");
+ assert(getSuperRegsComplete() && "TopoSigs haven't been computed yet.");
return TopoSig;
}
@@ -277,7 +290,8 @@ class CodeGenRegister {
RegUnitList getNativeRegUnits() const { return NativeRegUnits; }
void setRegUnitLaneMasks(const RegUnitLaneMaskList &LaneMasks) {
- RegUnitLaneMasks = LaneMasks;
+ if (RegUnitLaneMasks.data() != LaneMasks.data())
+ RegUnitLaneMasks.assign(LaneMasks.begin(), LaneMasks.end());
}
// Inherit register units from subregisters.
@@ -295,8 +309,10 @@ class CodeGenRegister {
using Vec = std::vector<const CodeGenRegister *>;
private:
- bool SubRegsComplete;
- bool SuperRegsComplete;
+ bool getSubRegsComplete() const { return ExplicitAliases.getFlag(0); }
+ void setSubRegsComplete(bool Value) { ExplicitAliases.setFlag(0, Value); }
+ bool getSuperRegsComplete() const { return ExplicitAliases.getFlag(1); }
+ void setSuperRegsComplete(bool Value) { ExplicitAliases.setFlag(1, Value); }
unsigned TopoSig;
// The sub-registers explicit in the .td file form a tree.
@@ -304,7 +320,7 @@ class CodeGenRegister {
SmallVector<CodeGenRegister *, 8> ExplicitSubRegs;
// Explicit ad hoc aliases, symmetrized to form an undirected graph.
- SmallVector<CodeGenRegister *, 8> ExplicitAliases;
+ llvm::SmallVectorWithFlags<CodeGenRegister *, 8, 2> ExplicitAliases;
// Super-registers where this is the first explicit sub-register.
SuperRegList LeadingSuperRegs;
@@ -313,7 +329,7 @@ class CodeGenRegister {
SuperRegList SuperRegs;
DenseMap<const CodeGenRegister *, CodeGenSubRegIndex *> SubReg2Idx;
RegUnitList RegUnits;
- RegUnitLaneMaskList RegUnitLaneMasks;
+ llvm::SmallVectorWithFlagsFor<RegUnitLaneMaskList, 4> RegUnitLaneMasks;
};
inline bool operator<(const CodeGenRegister &A, const CodeGenRegister &B) {
@@ -338,7 +354,7 @@ class CodeGenRegisterClass {
BitVector SubClasses;
// List of super-classes, topologocally ordered to have the larger classes
// first. This is the same as sorting by EnumValue.
- SmallVector<CodeGenRegisterClass *, 4> SuperClasses;
+ llvm::SmallVectorWithFlags<CodeGenRegisterClass *, 4, 2> SuperClasses;
const Record *TheDef;
std::string Name;
@@ -372,25 +388,31 @@ class CodeGenRegisterClass {
public:
unsigned EnumValue;
StringRef Namespace;
- SmallVector<ValueTypeByHwMode, 4> VTs;
+ llvm::SmallVectorWithFlags<ValueTypeByHwMode, 4, 4> VTs;
RegSizeInfoByHwMode RSI;
uint8_t CopyCost;
- bool Allocatable;
+ bool getAllocatable() const { return VTs.getFlag(0); }
+ void setAllocatable(bool Value) { VTs.setFlag(0, Value); }
StringRef AltOrderSelect;
uint8_t AllocationPriority;
- bool GlobalPriority;
+ bool getGlobalPriority() const { return VTs.getFlag(1); }
+ void setGlobalPriority(bool Value) { VTs.setFlag(1, Value); }
uint8_t TSFlags;
uint8_t SpillStackID;
/// Contains the combination of the lane masks of all subregisters.
LaneBitmask LaneMask;
/// True if there are at least 2 subregisters which do not interfere.
- bool HasDisjunctSubRegs;
- bool CoveredBySubRegs;
+ bool getHasDisjunctSubRegs() const { return VTs.getFlag(2); }
+ void setHasDisjunctSubRegs(bool Value) { VTs.setFlag(2, Value); }
+ bool getCoveredBySubRegs() const { return VTs.getFlag(3); }
+ void setCoveredBySubRegs(bool Value) { VTs.setFlag(3, Value); }
/// A register class is artificial if all its members are artificial.
- bool Artificial;
+ bool getArtificial() const { return SuperClasses.getFlag(0); }
+ void setArtificial(bool Value) { SuperClasses.setFlag(0, Value); }
/// Generate register pressure set for this register class and any class
/// synthesized from it.
- bool GeneratePressureSet;
+ bool getGeneratePressureSet() const { return SuperClasses.getFlag(1); }
+ void setGeneratePressureSet(bool Value) { SuperClasses.setFlag(1, Value); }
// Return the Record that defined this class, or NULL if the class was
// created by TableGen.
@@ -647,7 +669,7 @@ class CodeGenRegBank {
const CodeGenHwModes &CGH;
- const bool RegistersAreIntervals;
+ bool getRegistersAreIntervals() const { return RegUnits.getFlag(0); }
std::deque<CodeGenSubRegIndex> SubRegIndices;
DenseMap<const Record *, CodeGenSubRegIndex *> Def2SubRegIdx;
@@ -670,7 +692,7 @@ class CodeGenRegBank {
std::map<TopoSigId, unsigned> TopoSigs;
// Includes native (0..NumNativeRegUnits-1) and adopted register units.
- SmallVector<RegUnit, 8> RegUnits;
+ llvm::SmallVectorWithFlags<RegUnit, 8> RegUnits;
// Register classes.
std::list<CodeGenRegisterClass> RegClasses;
@@ -818,9 +840,9 @@ class CodeGenRegBank {
RegUnit &RU = RegUnits.emplace_back();
RU.Roots[0] = R0;
RU.Roots[1] = R1;
- RU.Artificial = R0->Artificial;
+ RU.Artificial = R0->getArtificial();
if (R1)
- RU.Artificial |= R1->Artificial;
+ RU.Artificial |= R1->getArtificial();
return RegUnits.size() - 1;
}
diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.cpp b/llvm/utils/TableGen/Common/CodeGenTarget.cpp
index ba6c938d88bcd..d23752dfe60d3 100644
--- a/llvm/utils/TableGen/Common/CodeGenTarget.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenTarget.cpp
@@ -272,7 +272,8 @@ void CodeGenTarget::ReadInstructions() const {
for (const Record *R : Insts) {
auto [II, _] =
InstructionMap.try_emplace(R, std::make_unique<CodeGenInstruction>(R));
- HasVariableLengthEncodings |= II->second->isVariableLengthEncoding();
+ setHasVariableLengthEncodings(int(getHasVariableLengthEncodings()) |
+ II->second->isVariableLengthEncoding());
}
}
diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.h b/llvm/utils/TableGen/Common/CodeGenTarget.h
index c04d331357b28..1fc9342e41757 100644
--- a/llvm/utils/TableGen/Common/CodeGenTarget.h
+++ b/llvm/utils/TableGen/Common/CodeGenTarget.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include <cassert>
@@ -62,11 +63,16 @@ class CodeGenTarget {
InstructionMap;
mutable std::unique_ptr<CodeGenRegBank> RegBank;
mutable ArrayRef<const Record *> RegAltNameIndices;
- mutable SmallVector<ValueTypeByHwMode, 8> LegalValueTypes;
+ mutable llvm::SmallVectorWithFlags<ValueTypeByHwMode, 8> LegalValueTypes;
mutable std::optional<std::vector<const Record *>> RegClassByHwModeList;
CodeGenHwModes CGH;
ArrayRef<const Record *> MacroFusions;
- mutable bool HasVariableLengthEncodings = false;
+ bool getHasVariableLengthEncodings() const {
+ return LegalValueTypes.getFlag(0);
+ }
+ void setHasVariableLengthEncodings(bool Value) const {
+ LegalValueTypes.setFlag(0, Value);
+ }
void ReadInstructions() const;
void ReadLegalValueTypes() const;
@@ -238,7 +244,9 @@ class CodeGenTarget {
}
/// Return whether instructions have variable length encodings on this target.
- bool hasVariableLengthEncodings() const { return HasVariableLengthEncodings; }
+ bool hasVariableLengthEncodings() const {
+ return getHasVariableLengthEncodings();
+ }
/// isLittleEndianEncoding - are instruction bit patterns defined as [0..n]?
///
diff --git a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
index 40ff769e7bf24..35a31e5cef69d 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp
@@ -477,7 +477,8 @@ void SwitchMatcher::emit(MatchTable &Table) {
//===- RuleMatcher --------------------------------------------------------===//
RuleMatcher::RuleMatcher(ArrayRef<SMLoc> SrcLoc, bool UsesRecordOperand)
- : Matcher(Matcher::MK_Rule), UsesRecordOperand(UsesRecordOperand),
+ : Matcher(Matcher::MK_Rule),
+ Roots(decltype(this->Roots)::withFlags(unsigned(!(UsesRecordOperand)))),
SrcLoc(SrcLoc), RuleID(NextRuleID++) {}
uint64_t RuleMatcher::NextRuleID = 0;
@@ -1485,12 +1486,14 @@ bool MIFlagsInstructionPredicateMatcher::isIdentical(
return false;
const auto &Other =
static_cast<const MIFlagsInstructionPredicateMatcher &>(B);
- return Flags == Other.Flags && CheckNot == Other.CheckNot;
+ return (llvm::ArrayRef<llvm::StringRef>(Flags) ==
+ llvm::ArrayRef<llvm::StringRef>(Other.Flags)) &&
+ getCheckNot() == Other.getCheckNot();
}
void MIFlagsInstructionPredicateMatcher::emitPredicateOpcodes(
MatchTable &Table) const {
- Table << MatchTable::Opcode(CheckNot ? "GIM_MIFlagsNot" : "GIM_MIFlags")
+ Table << MatchTable::Opcode(getCheckNot() ? "GIM_MIFlagsNot" : "GIM_MIFlags")
<< MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID)
<< MatchTable::NamedValue(4, join(Flags, " | "))
<< MatchTable::LineBreak;
diff --git a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
index 83a8b87ca3d61..43c4b0fbeeeb4 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
+++ b/llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGenTypes/LowLevelType.h"
@@ -296,7 +297,7 @@ class RuleMatcher : public Matcher {
/// extended to support multiple positions to support div/rem fusion or
/// load-multiple instructions.
using RootsTy = SmallVector<InstructionMatcher *, 1>;
- RootsTy Roots;
+ llvm::SmallVectorWithFlagsFor<RootsTy, 1> Roots;
/// A list of actions that need to be taken when all predicates in this rule
/// have succeeded.
@@ -342,7 +343,8 @@ class RuleMatcher : public Matcher {
/// When false, it means the back-end uses other means that we do not know
/// about and we thus need to assume ANY operand can be accessed by ANY C++
/// code (GenericInstructionPredicateMatcher)
- bool UsesRecordOperand = true;
+ bool getUsesRecordOperand() const { return !Roots.getFlag(0); }
+ void setUsesRecordOperand(bool Value) { Roots.setFlag(0, !Value); }
std::vector<std::string> RequiredSimplePredicates;
std::vector<const Record *> RequiredFeatures;
@@ -394,7 +396,7 @@ class RuleMatcher : public Matcher {
return RequiredFeatures;
}
- bool usesRecordOperand() const { return UsesRecordOperand; }
+ bool usesRecordOperand() const { return getUsesRecordOperand(); }
void addHwModeIdx(unsigned Idx) { HwModeIdx = Idx; }
int getHwModeIdx() const { return HwModeIdx; }
@@ -525,7 +527,9 @@ class RuleMatcher : public Matcher {
return make_range(PhysRegOperands.begin(), PhysRegOperands.end());
}
- iterator_range<RootsTy::iterator> roots() { return Roots; }
+ iterator_range<RootsTy::iterator> roots() {
+ return {Roots.begin(), Roots.end()};
+ }
bool roots_empty() const { return Roots.empty(); }
void roots_pop_front();
};
@@ -1552,15 +1556,19 @@ class GenericInstructionPredicateMatcher : public InstructionPredicateMatcher {
};
class MIFlagsInstructionPredicateMatcher : public InstructionPredicateMatcher {
- SmallVector<StringRef, 2> Flags;
- bool CheckNot; // false = GIM_MIFlags, true = GIM_MIFlagsNot
+ llvm::SmallVectorWithFlags<StringRef, 2> Flags;
+ bool getCheckNot() const { return Flags.getFlag(0); }
+ void setCheckNot(bool Value) {
+ Flags.setFlag(0, Value);
+ } // false = GIM_MIFlags, true = GIM_MIFlagsNot
public:
MIFlagsInstructionPredicateMatcher(unsigned InsnVarID,
ArrayRef<StringRef> FlagsToCheck,
bool CheckNot = false)
: InstructionPredicateMatcher(IPM_MIFlags, InsnVarID),
- Flags(FlagsToCheck), CheckNot(CheckNot) {
+ Flags(decltype(this->Flags)::withFlags(unsigned(CheckNot),
+ FlagsToCheck)) {
sort(Flags);
}
diff --git a/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp b/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp
index 8e4a8507e1aca..df84f4ac47aa8 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp
@@ -94,11 +94,11 @@ bool PatternParser::parsePatternList(
static const CodeGenInstruction &
getInstrForIntrinsic(const CodeGenTarget &CGT, const CodeGenIntrinsic *I) {
StringRef Opc;
- if (I->isConvergent) {
- Opc = I->hasSideEffects ? "G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS"
- : "G_INTRINSIC_CONVERGENT";
+ if (I->getIsConvergent()) {
+ Opc = I->getHasSideEffects() ? "G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS"
+ : "G_INTRINSIC_CONVERGENT";
} else {
- Opc = I->hasSideEffects ? "G_INTRINSIC_W_SIDE_EFFECTS" : "G_INTRINSIC";
+ Opc = I->getHasSideEffects() ? "G_INTRINSIC_W_SIDE_EFFECTS" : "G_INTRINSIC";
}
RecordKeeper &RK = I->TheDef->getRecords();
diff --git a/llvm/utils/TableGen/Common/InstructionEncoding.cpp b/llvm/utils/TableGen/Common/InstructionEncoding.cpp
index 1d36bd6d9f95c..96fa3c7256c02 100644
--- a/llvm/utils/TableGen/Common/InstructionEncoding.cpp
+++ b/llvm/utils/TableGen/Common/InstructionEncoding.cpp
@@ -411,7 +411,7 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef,
DecoderNamespace = EncodingDef->getValueAsString("DecoderNamespace");
DecoderMethod = EncodingDef->getValueAsString("DecoderMethod");
if (!DecoderMethod.empty())
- HasCompleteDecoder = EncodingDef->getValueAsBit("hasCompleteDecoder");
+ setHasCompleteDecoder(EncodingDef->getValueAsBit("hasCompleteDecoder"));
const RecordVal *InstField = EncodingDef->getValue("Inst");
if (const auto *DI = dyn_cast<DagInit>(InstField->getValue())) {
@@ -431,10 +431,10 @@ InstructionEncoding::InstructionEncoding(const Record *EncodingDef,
if (DecoderMethod.empty()) {
// A generated decoder is always successful if none of the operand
// decoders can fail (all are always successful).
- HasCompleteDecoder = all_of(Operands, [](const OperandInfo &Op) {
+ setHasCompleteDecoder(all_of(Operands, [](const OperandInfo &Op) {
// By default, a generated operand decoder is assumed to always succeed.
// This can be overridden by the user.
return Op.Decoder.empty() || Op.HasCompleteDecoder;
- });
+ }));
}
}
diff --git a/llvm/utils/TableGen/Common/InstructionEncoding.h b/llvm/utils/TableGen/Common/InstructionEncoding.h
index 44b45137b8f8c..5d15ce956ac22 100644
--- a/llvm/utils/TableGen/Common/InstructionEncoding.h
+++ b/llvm/utils/TableGen/Common/InstructionEncoding.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/KnownBits.h"
#include <optional>
@@ -80,10 +81,11 @@ class InstructionEncoding {
/// Whether the custom decoding function always succeeds. If a custom decoder
/// function is specified, the value is taken from the target description,
/// otherwise it is inferred.
- bool HasCompleteDecoder;
+ bool getHasCompleteDecoder() const { return Operands.getFlag(0); }
+ void setHasCompleteDecoder(bool Value) { Operands.setFlag(0, Value); }
/// Information about the operands' contribution to this encoding.
- SmallVector<OperandInfo, 16> Operands;
+ llvm::SmallVectorWithFlags<OperandInfo, 16> Operands;
public:
InstructionEncoding(const Record *EncodingDef,
@@ -127,7 +129,7 @@ class InstructionEncoding {
/// Returns whether the decoder (either generated or specified by the user)
/// always succeeds.
- bool hasCompleteDecoder() const { return HasCompleteDecoder; }
+ bool hasCompleteDecoder() const { return getHasCompleteDecoder(); }
/// Returns information about the operands' contribution to this encoding.
ArrayRef<OperandInfo> getOperands() const { return Operands; }
diff --git a/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp b/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp
index 3a2ef55656067..fa04472b5046a 100644
--- a/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp
+++ b/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp
@@ -127,7 +127,7 @@ getCustomCoders(ArrayRef<const Init *> Args) {
}
VarLenInst::VarLenInst(const DagInit *DI, const RecordVal *TheDef)
- : TheDef(TheDef), NumBits(0U), HasDynamicSegment(false) {
+ : TheDef(TheDef), NumBits(0U) {
buildRec(DI);
for (const auto &S : Segments)
NumBits += S.BitWidth;
@@ -168,7 +168,7 @@ void VarLenInst::buildRec(const DagInit *DI) {
if (DI->getNumArgs() < 2)
PrintFatalError(TheDef->getLoc(),
"Expecting at least 2 arguments for `operand`");
- HasDynamicSegment = true;
+ setHasDynamicSegment(true);
const Init *OperandName = DI->getArg(0), *NumBits = DI->getArg(1);
if (!isa<StringInit>(OperandName) || !isa<IntInit>(NumBits))
PrintFatalError(TheDef->getLoc(), "Invalid argument types for `operand`");
@@ -187,7 +187,7 @@ void VarLenInst::buildRec(const DagInit *DI) {
if (DI->getNumArgs() < 3)
PrintFatalError(TheDef->getLoc(),
"Expecting at least 3 arguments for `slice`");
- HasDynamicSegment = true;
+ setHasDynamicSegment(true);
const Init *OperandName = DI->getArg(0), *HiBit = DI->getArg(1),
*LoBit = DI->getArg(2);
if (!isa<StringInit>(OperandName) || !isa<IntInit>(HiBit) ||
diff --git a/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.h b/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.h
index ca0f9c3f8b4f3..9a98cbe70eb6d 100644
--- a/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.h
+++ b/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.h
@@ -14,6 +14,7 @@
#ifndef LLVM_UTILS_TABLEGEN_COMMON_VARLENCODEEMITTERGEN_H
#define LLVM_UTILS_TABLEGEN_COMMON_VARLENCODEEMITTERGEN_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/TableGen/Record.h"
namespace llvm {
@@ -30,14 +31,15 @@ class VarLenInst {
size_t NumBits;
// Set if any of the segment is not fixed value.
- bool HasDynamicSegment;
+ bool getHasDynamicSegment() const { return Segments.getFlag(0); }
+ void setHasDynamicSegment(bool Value) { Segments.setFlag(0, Value); }
- SmallVector<EncodingSegment, 4> Segments;
+ llvm::SmallVectorWithFlags<EncodingSegment, 4> Segments;
void buildRec(const DagInit *DI);
public:
- VarLenInst() : TheDef(nullptr), NumBits(0U), HasDynamicSegment(false) {}
+ VarLenInst() : TheDef(nullptr), NumBits(0U) {}
explicit VarLenInst(const DagInit *DI, const RecordVal *TheDef);
@@ -50,7 +52,7 @@ class VarLenInst {
const_iterator end() const { return Segments.end(); }
size_t getNumSegments() const { return Segments.size(); }
- bool isFixedValueOnly() const { return !HasDynamicSegment; }
+ bool isFixedValueOnly() const { return !getHasDynamicSegment(); }
};
void emitVarLenCodeEmitter(const RecordKeeper &R, raw_ostream &OS);
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index f8ebdfccda46f..ae45cd9824fe3 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -289,7 +290,7 @@ class FilterChooser {
/// Encoding IDs for this filter chooser to work on.
/// Sorted by non-decreasing encoding width.
- SmallVector<unsigned, 0> EncodingIDs;
+ llvm::SmallVectorWithFlags<unsigned, 0> EncodingIDs;
// Array of bit values passed down from our parent.
// Set to all unknown for Parent == nullptr.
@@ -323,7 +324,8 @@ class FilterChooser {
std::map<uint64_t, std::unique_ptr<const FilterChooser>> FilterChooserMap;
/// Set to true if decoding conflict was encountered.
- bool HasConflict = false;
+ bool getHasConflict() const { return EncodingIDs.getFlag(0); }
+ void setHasConflict(bool Value) { EncodingIDs.setFlag(0, Value); }
public:
/// Constructs a top-level filter chooser.
@@ -362,7 +364,7 @@ class FilterChooser {
}
/// Returns true if any decoding conflicts were encountered.
- bool hasConflict() const { return HasConflict; }
+ bool hasConflict() const { return getHasConflict(); }
private:
/// Applies the given filter to the set of encodings this FilterChooser
@@ -438,7 +440,10 @@ void FilterChooser::applyFilter(const Filter &F) {
// group of instructions whose segment values are variable.
VariableFC = std::make_unique<FilterChooser>(Encodings, F.VariableIDs,
FilterBits, *this);
- HasConflict |= VariableFC->HasConflict;
+ [&] {
+ auto PackedFlagValue = VariableFC->getHasConflict();
+ return setHasConflict(getHasConflict() | PackedFlagValue);
+ }();
}
// Otherwise, create sub choosers.
@@ -454,7 +459,7 @@ void FilterChooser::applyFilter(const Filter &F) {
FilterVal,
std::make_unique<FilterChooser>(Encodings, InferiorEncodingIDs,
InferiorFilterBits, *this));
- HasConflict |= It->second->HasConflict;
+ setHasConflict(int(getHasConflict()) | It->second->getHasConflict());
}
}
@@ -802,7 +807,8 @@ FilterChooser::findBestFilter(ArrayRef<bitAttr_t> BitAttrs, bool AllowMixed,
if (!Islands.empty()) {
// Found an instruction with island(s). Now just assign a filter.
return std::make_unique<Filter>(
- Encodings, EncodingIDs, Islands[0].StartBit, Islands[0].NumBits);
+ Encodings, ArrayRef<unsigned>(EncodingIDs), Islands[0].StartBit,
+ Islands[0].NumBits);
}
}
}
@@ -833,8 +839,9 @@ FilterChooser::findBestFilter(ArrayRef<bitAttr_t> BitAttrs, bool AllowMixed,
std::vector<std::unique_ptr<Filter>> Filters;
auto addCandidateFilter = [&](unsigned StartBit, unsigned EndBit) {
- Filters.push_back(std::make_unique<Filter>(Encodings, EncodingIDs, StartBit,
- EndBit - StartBit));
+ Filters.push_back(std::make_unique<Filter>(Encodings,
+ ArrayRef<unsigned>(EncodingIDs),
+ StartBit, EndBit - StartBit));
};
unsigned FilterWidth = FilterBits.getBitWidth();
@@ -1038,7 +1045,7 @@ void FilterChooser::doFilter() {
// Print out useful conflict information for postmortem analysis.
errs() << "Decoding Conflict:\n";
dump();
- HasConflict = true;
+ setHasConflict(true);
}
void FilterChooser::dump() const {
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index be335ce3bc34c..3f72b9f3052e9 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -553,7 +553,7 @@ GlobalISelEmitter::getEquivNode(const Record &Equiv,
}
if (!Equiv.isValueUnset("IfConvergent") &&
- N.getIntrinsicInfo(CGP)->isConvergent)
+ N.getIntrinsicInfo(CGP)->getIsConvergent())
return &Target.getInstruction(Equiv.getValueAsDef("IfConvergent"));
bool IsAnyExtLoad = false;
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index ccce8fb0fedbf..d15025c28a9c3 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -247,7 +247,7 @@ void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS,
const CodeGenRegister::Vec &Regs = RC.getMembers();
OS << " {" << RC.getWeight(RegBank) << ", ";
unsigned WeightLimit = 0;
- if (Regs.empty() || RC.Artificial)
+ if (Regs.empty() || RC.getArtificial())
OS << '0';
else {
std::vector<unsigned> RegUnits;
@@ -1080,8 +1080,8 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
<< DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i])
<< ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
<< (Offset << RegUnitBits | FirstRU) << ", "
- << LaneMaskSeqs.get(RegUnitLaneMasks[i]) << ", " << Reg.Constant << ", "
- << Reg.Artificial << " },\n";
+ << LaneMaskSeqs.get(RegUnitLaneMasks[i]) << ", " << Reg.getConstant()
+ << ", " << Reg.getArtificial() << " },\n";
++i;
}
OS << "};\n\n"; // End of register descriptors...
@@ -1241,7 +1241,8 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
<< RCIndices.RegSetSize << ", /* RegSetSize */\n "
<< RC.getQualifiedIdName() << ",\n "
<< static_cast<unsigned>(RC.CopyCost) << ", /* CopyCost */\n "
- << (RC.Allocatable ? "true" : "false") << ", /* Allocatable */\n "
+ << (RC.getAllocatable() ? "true" : "false")
+ << ", /* Allocatable */\n "
<< (RC.getBaseClassOrder() ? "true" : "false") << ",\n "
<< GetOff("SubClassMasks", RCIndices.SubClassMaskIdx) << ",\n "
<< GetOff("SuperRegIdxSeqs",
@@ -1249,12 +1250,12 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS,
<< ",\n ";
printMask(OS, RC.LaneMask);
OS << ",\n " << (unsigned)RC.AllocationPriority << ",\n "
- << (RC.GlobalPriority ? "true" : "false") << ",\n "
+ << (RC.getGlobalPriority() ? "true" : "false") << ",\n "
<< format("0x%02x", RC.TSFlags) << ", /* TSFlags */\n "
<< (unsigned)RC.SpillStackID << ", /* SpillStackID */\n "
- << (RC.HasDisjunctSubRegs ? "true" : "false")
+ << (RC.getHasDisjunctSubRegs() ? "true" : "false")
<< ", /* HasDisjunctSubRegs */\n "
- << (RC.CoveredBySubRegs ? "true" : "false")
+ << (RC.getCoveredBySubRegs() ? "true" : "false")
<< ", /* CoveredBySubRegs */\n "
<< GetOff("SuperClasses", RCIndices.SuperClassIdx) << ",\n "
<< RC.getSuperClasses().size() << "\n },\n";
@@ -1523,7 +1524,7 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
for (const auto &RC : RegisterClasses) {
ArrayRef<const Record *> Order = RC.getOrder();
- if (RC.Allocatable)
+ if (RC.getAllocatable())
AllocatableRegs.insert(Order.begin(), Order.end());
}
@@ -1955,7 +1956,7 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
// Add all constant physical registers to the preserved mask:
SetTheory::RecSet ConstantSet;
for (const auto &Reg : RegBank.getRegisters()) {
- if (Reg.Constant)
+ if (Reg.getConstant())
ConstantSet.insert(Reg.TheDef);
}
Covered |= RegBank.computeCoveredRegisters(ConstantSet.getArrayRef());
@@ -2041,7 +2042,7 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
<< "isConstantPhysReg(MCRegister PhysReg) const {\n"
<< " return\n";
for (const auto &Reg : Regs)
- if (Reg.Constant)
+ if (Reg.getConstant())
OS << " PhysReg == " << getQualifiedName(Reg.TheDef) << " ||\n";
OS << " false;\n";
OS << "}\n\n";
@@ -2135,9 +2136,9 @@ void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
<< '\n';
OS << "\tNumRegs: " << RC.getMembers().size() << '\n';
OS << "\tLaneMask: " << PrintLaneMask(RC.LaneMask) << '\n';
- OS << "\tHasDisjunctSubRegs: " << RC.HasDisjunctSubRegs << '\n';
- OS << "\tCoveredBySubRegs: " << RC.CoveredBySubRegs << '\n';
- OS << "\tAllocatable: " << RC.Allocatable << '\n';
+ OS << "\tHasDisjunctSubRegs: " << RC.getHasDisjunctSubRegs() << '\n';
+ OS << "\tCoveredBySubRegs: " << RC.getCoveredBySubRegs() << '\n';
+ OS << "\tAllocatable: " << RC.getAllocatable() << '\n';
OS << "\tAllocationPriority: " << unsigned(RC.AllocationPriority) << '\n';
OS << "\tWeight: " << RC.getWeight(RegBank) << '\n';
OS << "\tBaseClassOrder: " << RC.getBaseClassOrder() << '\n';
@@ -2159,21 +2160,21 @@ void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
OS << " " << SRC->getName();
}
OS << '\n';
- if (RC.Artificial)
+ if (RC.getArtificial())
OS << "\tArtificial: 1\n";
}
for (const CodeGenSubRegIndex &SRI : RegBank.getSubRegIndices()) {
OS << "SubRegIndex " << SRI.getName() << ":\n";
OS << "\tLaneMask: " << PrintLaneMask(SRI.LaneMask) << '\n';
- OS << "\tAllSuperRegsCovered: " << SRI.AllSuperRegsCovered << '\n';
+ OS << "\tAllSuperRegsCovered: " << SRI.getAllSuperRegsCovered() << '\n';
OS << "\tOffset: " << printByHwMode(SRI.Range, [](const SubRegRange &Info) {
return Info.Offset;
}) << '\n';
OS << "\tSize: " << printByHwMode(SRI.Range, [](const SubRegRange &Info) {
return Info.Size;
}) << '\n';
- if (SRI.Artificial)
+ if (SRI.getArtificial())
OS << "\tArtificial: 1\n";
}
@@ -2183,15 +2184,15 @@ void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
for (const auto &Cost : R.CostPerUse)
OS << Cost << " ";
OS << '\n';
- OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';
- OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';
+ OS << "\tCoveredBySubregs: " << R.getCoveredBySubRegs() << '\n';
+ OS << "\tHasDisjunctSubRegs: " << R.getHasDisjunctSubRegs() << '\n';
for (auto &[SubIdx, SubReg] : R.getSubRegs()) {
OS << "\tSubReg " << SubIdx->getName() << " = " << SubReg->getName()
<< '\n';
}
for (unsigned U : R.getNativeRegUnits())
OS << "\tRegUnit " << U << '\n';
- if (R.Artificial)
+ if (R.getArtificial())
OS << "\tArtificial: 1\n";
}
}
diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp
index c43471b32911d..ef7277006bbcc 100644
--- a/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
@@ -80,9 +81,11 @@ struct GenericField {
struct SearchIndex {
std::string Name;
SMLoc Loc; // Source location of PrimaryKey or Key field definition.
- SmallVector<GenericField, 1> Fields;
- bool EarlyOut = false;
- bool ReturnRange = false;
+ llvm::SmallVectorWithFlags<GenericField, 1, 2> Fields;
+ bool getEarlyOut() const { return Fields.getFlag(0); }
+ void setEarlyOut(bool Value) { Fields.setFlag(0, Value); }
+ bool getReturnRange() const { return Fields.getFlag(1); }
+ void setReturnRange(bool Value) { Fields.setFlag(1, Value); }
};
struct GenericTable {
@@ -94,9 +97,10 @@ struct GenericTable {
std::vector<const Record *> Entries;
std::unique_ptr<SearchIndex> PrimaryKey;
- SmallVector<std::unique_ptr<SearchIndex>, 2> Indices;
+ llvm::SmallVectorWithFlags<std::unique_ptr<SearchIndex>, 2> Indices;
- bool AllowSparseTable;
+ bool getAllowSparseTable() const { return Indices.getFlag(0); }
+ void setAllowSparseTable(bool Value) { Indices.setFlag(0, Value); }
const GenericField *getFieldByName(StringRef Name) const {
for (const auto &Field : Fields) {
@@ -442,7 +446,7 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
}
}
- if (Index.EarlyOut || IsContiguous) {
+ if (Index.getEarlyOut() || IsContiguous) {
const GenericField &Field = Index.Fields[0];
std::string FirstRepr = primaryRepresentation(
Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name));
@@ -454,7 +458,7 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
<< ">(" << Field.Name << ", " << FirstRepr << ", " << LastRepr << "))\n";
OS << " return nullptr;\n\n";
- if (IsContiguous && !Index.EarlyOut) {
+ if (IsContiguous && !Index.getEarlyOut()) {
OS << " auto Table = ArrayRef(" << IndexName << ");\n";
OS << " size_t Idx = " << Field.Name << " - " << FirstRepr << ";\n";
OS << " return ";
@@ -538,7 +542,7 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
OS << " }\n";
};
emitComparator(false, true);
- bool ShouldReturnRange = Index.ReturnRange;
+ bool ShouldReturnRange = Index.getReturnRange();
if (ShouldReturnRange) {
OS << " bool operator()(const KeyType &LHS, const " << IndexTypeName
<< " &RHS) const {\n";
@@ -580,7 +584,7 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table,
void SearchableTableEmitter::emitLookupDeclaration(const GenericTable &Table,
const SearchIndex &Index,
raw_ostream &OS) {
- if (Index.ReturnRange)
+ if (Index.getReturnRange())
OS << "llvm::iterator_range<const " << Table.CppTypeName << " *> ";
else
OS << "const " << Table.CppTypeName << " *";
@@ -621,7 +625,7 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table,
SmallVector<const Record *, 0> SparseEntries;
ArrayRef<const Record *> Entries;
unsigned DirectLookupSlots = 0;
- if (Table.AllowSparseTable) {
+ if (Table.getAllowSparseTable()) {
const auto *KeyBits = cast<BitsRecTy>(Table.PrimaryKey->Fields[0].RecType);
DirectLookupSlots = 1u << KeyBits->getNumBits();
SparseEntries.resize(DirectLookupSlots);
@@ -658,7 +662,7 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table,
OS << primaryRepresentation(Table.Locs[0], Field, Value);
}
}
- } else if (Table.AllowSparseTable) {
+ } else if (Table.getAllowSparseTable()) {
// For empty rows emit a sentinel value as a key, so we can return null
// during lookup. Value is constructed such that LookupKey != KeyField.
for (const auto &Field : Table.Fields) {
@@ -677,7 +681,7 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table,
// The lookup function might add more strings.
std::string LookupFunction;
raw_string_ostream LFOS(LookupFunction);
- if (Table.AllowSparseTable) {
+ if (Table.getAllowSparseTable()) {
LFOS << "\n";
emitLookupDeclaration(Table, *Table.PrimaryKey, LFOS);
LFOS << " {\n";
@@ -741,8 +745,8 @@ std::unique_ptr<SearchIndex> SearchableTableEmitter::parseSearchIndex(
auto Index = std::make_unique<SearchIndex>();
Index->Name = Name.str();
Index->Loc = KeyRecVal->getLoc();
- Index->EarlyOut = EarlyOut;
- Index->ReturnRange = ReturnRange;
+ Index->setEarlyOut(EarlyOut);
+ Index->setReturnRange(ReturnRange);
for (const auto &FieldName : Key) {
const GenericField *Field = Table.getFieldByName(FieldName);
@@ -979,7 +983,7 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
return compareBy(LHS, RHS, *Table->PrimaryKey);
});
- Table->AllowSparseTable = canUseSparseTable(TableRec, Table);
+ Table->setAllowSparseTable(canUseSparseTable(TableRec, Table));
}
TableMap.try_emplace(TableRec, Table.get());
@@ -1003,7 +1007,7 @@ void SearchableTableEmitter::run(raw_ostream &OS) {
IndexRec->getValueAsBit("EarlyOut"), /*ReturnRange*/ false));
// Sparse tables with secondary search indices are not supported.
- Table.AllowSparseTable = false;
+ Table.setAllowSparseTable(false);
}
// Translate legacy tables.
diff --git a/mlir/examples/transform-opt/mlir-transform-opt.cpp b/mlir/examples/transform-opt/mlir-transform-opt.cpp
index 4b12e7610d0a8..76d81a019cccd 100644
--- a/mlir/examples/transform-opt/mlir-transform-opt.cpp
+++ b/mlir/examples/transform-opt/mlir-transform-opt.cpp
@@ -20,6 +20,7 @@
#include "mlir/Parser/Parser.h"
#include "mlir/Support/FileUtilities.h"
#include "mlir/Tools/mlir-opt/MlirOptMain.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/ManagedStatic.h"
@@ -175,8 +176,9 @@ class TransformSourceMgr {
/// Deconstructs the source manager. Note that `checkResults` must have been
/// called on this instance before deconstructing it.
~TransformSourceMgr() {
- assert(resultChecked && "must check the result of diagnostic handlers by "
- "running TransformSourceMgr::checkResult");
+ assert(getResultChecked() &&
+ "must check the result of diagnostic handlers by "
+ "running TransformSourceMgr::checkResult");
}
/// Parses the given buffer and creates the top-level operation of the kind
@@ -213,7 +215,7 @@ class TransformSourceMgr {
/// this source manager, performs the verification, reports errors and returns
/// the result of the verification. Otherwise passes through the given value.
llvm::LogicalResult checkResult(llvm::LogicalResult result) {
- resultChecked = true;
+ setResultChecked(true);
if (!verifyDiagnostics)
return result;
@@ -229,7 +231,8 @@ class TransformSourceMgr {
/// Indicates that diagnostic message verification has taken place, and the
/// deconstruction is therefore safe.
- bool resultChecked = false;
+ bool getResultChecked() const { return diagHandlers.getFlag(0); }
+ void setResultChecked(bool Value) { diagHandlers.setFlag(0, Value); }
/// Storage for per-buffer source managers and diagnostic handlers. These are
/// wrapped into unique pointers in order to make it safe to capture
@@ -237,7 +240,7 @@ class TransformSourceMgr {
/// pointer objects are moved by the pointer addresses won't change. Also, for
/// handlers, this allows to store the pointer to the base class.
SmallVector<std::unique_ptr<llvm::SourceMgr>> sourceMgrs;
- SmallVector<DiagnosticHandlerWrapper> diagHandlers;
+ llvm::SmallVectorWithFlags<DiagnosticHandlerWrapper> diagHandlers;
};
} // namespace
diff --git a/mlir/include/mlir/ABI/ABIRewriteContext.h b/mlir/include/mlir/ABI/ABIRewriteContext.h
index 7760d015d8919..3c6d653ce9443 100644
--- a/mlir/include/mlir/ABI/ABIRewriteContext.h
+++ b/mlir/include/mlir/ABI/ABIRewriteContext.h
@@ -25,6 +25,7 @@
#include "mlir/IR/Value.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/Alignment.h"
#include <cassert>
@@ -148,7 +149,8 @@ struct ArgClassification {
/// all arguments.
struct FunctionClassification {
ArgClassification returnInfo;
- SmallVector<ArgClassification> argInfos;
+ // Flag bit 0 marks a source-language void return.
+ llvm::SmallVectorWithFlags<ArgClassification> argInfos;
/// Whether the classified return type was the source language's void.
///
@@ -163,12 +165,13 @@ struct FunctionClassification {
///
/// Left false when unknown, which costs a needless rewrite rather than a
/// skipped one.
- bool returnsVoid = false;
+ bool returnsVoid() const { return argInfos.getFlag(0); }
+ void setReturnsVoid(bool IsVoid) { argInfos.setFlag(0, IsVoid); }
/// Whether any value in the signature is passed differently from how it is
/// written, so a rewriter has work to do.
bool needsRewrite() const {
- if (!returnsVoid && !returnInfo.isPassThrough())
+ if (!returnsVoid() && !returnInfo.isPassThrough())
return true;
return !llvm::all_of(argInfos, [](const ArgClassification &ac) {
return ac.isPassThrough();
diff --git a/mlir/include/mlir/Analysis/Presburger/Simplex.h b/mlir/include/mlir/Analysis/Presburger/Simplex.h
index d89bbe37a6b3e..33f862e964550 100644
--- a/mlir/include/mlir/Analysis/Presburger/Simplex.h
+++ b/mlir/include/mlir/Analysis/Presburger/Simplex.h
@@ -21,6 +21,7 @@
#include "mlir/Analysis/Presburger/PWMAFunction.h"
#include "mlir/Analysis/Presburger/Utils.h"
#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <optional>
namespace mlir {
@@ -318,12 +319,13 @@ class SimplexBase {
/// Return the number of fixed columns, as described in the constructor above,
/// this is the number of columns beyond those for the variables in var.
- unsigned getNumFixedCols() const { return usingBigM ? 3u : 2u; }
+ unsigned getNumFixedCols() const { return getUsingBigM() ? 3u : 2u; }
unsigned getNumRows() const { return tableau.getNumRows(); }
unsigned getNumColumns() const { return tableau.getNumColumns(); }
/// Stores whether or not a big M column is present in the tableau.
- bool usingBigM;
+ bool getUsingBigM() const { return var.getFlag(0); }
+ void setUsingBigM(bool Value) { var.setFlag(0, Value); }
/// The number of redundant rows in the tableau. These are the first
/// nRedundant rows.
@@ -338,7 +340,8 @@ class SimplexBase {
/// This is true if the tableau has been detected to be empty, false
/// otherwise.
- bool empty;
+ bool getEmpty() const { return var.getFlag(1); }
+ void setEmpty(bool Value) { var.setFlag(1, Value); }
/// Holds a log of operations, used for rolling back to a previous state.
SmallVector<UndoLogEntry, 8> undoLog;
@@ -358,7 +361,8 @@ class SimplexBase {
SmallVector<int, 8> rowUnknown, colUnknown;
/// These hold information about each unknown.
- SmallVector<Unknown, 8> con, var;
+ SmallVector<Unknown, 8> con;
+ llvm::SmallVectorWithFlags<Unknown, 8, 2> var;
};
/// Simplex class using the lexicographic pivot rule. Used for lexicographic
diff --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
index bec14fffec96c..3e9ee0328e3a3 100644
--- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
+++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
@@ -14,6 +14,7 @@
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/DenseMapInfoVariant.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <optional>
#include "mlir/Dialect/Bufferization/IR/BufferizationEnums.h.inc"
@@ -361,7 +362,12 @@ struct BufferizationOptions {
/// `functionArgTypeConverterFn`.
///
/// If `bufferizeFunctionBoundaries` is not set, this flag has no effect.
- bool inferFunctionResultLayout = true;
+ bool getInferFunctionResultLayout() const {
+ return !stateInitializers.getFlag(0);
+ }
+ void setInferFunctionResultLayout(bool Value) {
+ stateInitializers.setFlag(0, !Value);
+ }
/// Type conversion from tensors to memrefs. This type conversion is used if
/// no memref type could be inferred during bufferization. By default, returns
@@ -402,7 +408,7 @@ struct BufferizationOptions {
/// Initializer functions for analysis state. These can be used to
/// initialize dialect-specific analysis state.
- SmallVector<AnalysisStateInitFn> stateInitializers;
+ llvm::SmallVectorWithFlags<AnalysisStateInitFn> stateInitializers;
};
/// Traversal parameters for `findValueInReverseUseDefChain`.
diff --git a/mlir/include/mlir/Dialect/LLVMIR/BasicPtxBuilderInterface.h b/mlir/include/mlir/Dialect/LLVMIR/BasicPtxBuilderInterface.h
index cb2489335a317..e4c86a3cc4843 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/BasicPtxBuilderInterface.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/BasicPtxBuilderInterface.h
@@ -18,6 +18,7 @@
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/IR/Value.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/LogicalResult.h"
namespace mlir {
@@ -69,18 +70,29 @@ class PtxBuilder {
// Register constraints (read, write, readwrite) and register data types
std::string registerConstraints;
// Modifiers
- SmallVector<PTXRegisterMod> registerModifiers;
+ llvm::SmallVectorWithFlags<
+ PTXRegisterMod,
+ llvm::CalculateSmallVectorDefaultInlinedElements<PTXRegisterMod>::value,
+ 2>
+ registerModifiers;
// Has return value as write-only or read-write
- bool hasResult = false;
+ bool getHasResult() const { return registerModifiers.getFlag(0); }
+ void setHasResult(bool Value) { registerModifiers.setFlag(0, Value); }
// Indicates if the Op will handle the register mapping manually.
- bool needsManualRegisterMapping = false;
+ bool getNeedsManualRegisterMapping() const {
+ return registerModifiers.getFlag(1);
+ }
+ void setNeedsManualRegisterMapping(bool Value) {
+ registerModifiers.setFlag(1, Value);
+ }
public:
/// Single constructor that only initializes members.
PtxBuilder(Operation *op, PatternRewriter &rewriter,
bool needsManualRegisterMapping = false)
: interfaceOp(op), rewriter(rewriter),
- needsManualRegisterMapping(needsManualRegisterMapping) {}
+ registerModifiers(decltype(this->registerModifiers)::withFlags(
+ (unsigned(needsManualRegisterMapping) << 1))) {}
/// Add an operand with the read/write input type.
LogicalResult insertValue(Value v,
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index 575b8c20b790c..f4a77bb267452 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -9,6 +9,7 @@
#ifndef MLIR_DIALECT_LINALG_TRANSFORMS_TRANSFORMS_H
#define MLIR_DIALECT_LINALG_TRANSFORMS_TRANSFORMS_H
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <utility>
#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
@@ -356,16 +357,17 @@ struct PadTilingInterfaceOptions {
return *this;
}
/// A list of iterator dimensions sizes to pad to.
- SmallVector<OpFoldResult> paddingSizes;
+ llvm::SmallVectorWithFlags<OpFoldResult> paddingSizes;
PadTilingInterfaceOptions &setPaddingSizes(ArrayRef<OpFoldResult> m) {
paddingSizes.assign(m.begin(), m.end());
return *this;
}
/// Pad iterator `paddingDimension[i]` to next multiple of `paddingSizes[i]`
/// if true. Otherwise pad to `paddingSizes[i]`.
- bool padToMultipleOf;
+ bool getPadToMultipleOfFlag() const { return paddingSizes.getFlag(0); }
+ void setPadToMultipleOfFlag(bool Value) { paddingSizes.setFlag(0, Value); }
PadTilingInterfaceOptions &setPadToMultipleOf(bool b) {
- padToMultipleOf = b;
+ setPadToMultipleOfFlag(b);
return *this;
}
};
@@ -1421,29 +1423,54 @@ struct BlockPackMatmulOptions {
/// Scalable flags for block factors. When true, the corresponding block
/// factor is considered scalable. Must be empty (all static) or have the same
/// size as blockFactors.
- SmallVector<bool, 3> scalableBlockFactors;
+ llvm::SmallVectorWithFlags<bool, 3> scalableBlockFactors;
/// If true, allows packing of dimensions that only partially fit into the
/// block factors.
- bool allowPadding = true;
+ bool getAllowPadding() const {
+ return !mnkPaddedSizesNextMultipleOf.getFlag(0);
+ }
+ void setAllowPadding(bool Value) {
+ mnkPaddedSizesNextMultipleOf.setFlag(0, !Value);
+ }
/// Next multiples of the packing sizes.
- SmallVector<int64_t, 3> mnkPaddedSizesNextMultipleOf;
+ llvm::SmallVectorWithFlags<int64_t, 3, 4> mnkPaddedSizesNextMultipleOf;
/// Permutation of matmul (M, N, K) dimensions order.
SmallVector<int64_t, 3> mnkOrder = {0, 1, 2};
/// Transpose LHS outer block layout [MB][KB] -> [KB][MB].
- bool lhsTransposeOuterBlocks = false;
+ bool getLhsTransposeOuterBlocks() const {
+ return mnkPaddedSizesNextMultipleOf.getFlag(1);
+ }
+ void setLhsTransposeOuterBlocks(bool Value) {
+ mnkPaddedSizesNextMultipleOf.setFlag(1, Value);
+ }
/// Transpose LHS inner block layout [mb][kb] -> [kb][mb].
- bool lhsTransposeInnerBlocks = false;
+ bool getLhsTransposeInnerBlocks() const {
+ return mnkPaddedSizesNextMultipleOf.getFlag(2);
+ }
+ void setLhsTransposeInnerBlocks(bool Value) {
+ mnkPaddedSizesNextMultipleOf.setFlag(2, Value);
+ }
/// Transpose RHS outer block layout [KB][NB] -> [NB][KB].
- bool rhsTransposeOuterBlocks = true;
+ bool getRhsTransposeOuterBlocks() const {
+ return !mnkPaddedSizesNextMultipleOf.getFlag(3);
+ }
+ void setRhsTransposeOuterBlocks(bool Value) {
+ mnkPaddedSizesNextMultipleOf.setFlag(3, !Value);
+ }
/// Transpose RHS inner block layout [kb][nb] -> [nb][kb].
- bool rhsTransposeInnerBlocks = true;
+ bool getRhsTransposeInnerBlocks() const {
+ return !scalableBlockFactors.getFlag(0);
+ }
+ void setRhsTransposeInnerBlocks(bool Value) {
+ scalableBlockFactors.setFlag(0, !Value);
+ }
};
/// Function type which is used to control matmul packing.
diff --git a/mlir/include/mlir/Dialect/Shard/IR/ShardOps.h b/mlir/include/mlir/Dialect/Shard/IR/ShardOps.h
index e4ba0293d398f..fbc92ef951943 100644
--- a/mlir/include/mlir/Dialect/Shard/IR/ShardOps.h
+++ b/mlir/include/mlir/Dialect/Shard/IR/ShardOps.h
@@ -106,8 +106,8 @@ inline bool isReductionLoop(utils::IteratorType iType) {
}
// Remove empty subarrays of `array` until a minimum lengh of one is reached.
-template <typename T>
-void removeTrailingEmptySubArray(SmallVector<SmallVector<T>> &array) {
+template <typename RangeT>
+void removeTrailingEmptySubArray(RangeT &array) {
while (array.size() > 1 && array.back().empty())
array.pop_back();
}
diff --git a/mlir/include/mlir/Dialect/Shard/Interfaces/ShardingInterface.h b/mlir/include/mlir/Dialect/Shard/Interfaces/ShardingInterface.h
index 46f6ed410ebed..ba9d091e9aa2b 100644
--- a/mlir/include/mlir/Dialect/Shard/Interfaces/ShardingInterface.h
+++ b/mlir/include/mlir/Dialect/Shard/Interfaces/ShardingInterface.h
@@ -13,6 +13,7 @@
#include "mlir/Dialect/Utils/StructuredOpsUtils.h"
#include "mlir/IR/Value.h"
#include "mlir/Support/LLVM.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace mlir {
@@ -28,20 +29,24 @@ using ShardingArrayRef = ArrayRef<SmallVector<GridAxis>>;
struct ShardingOption {
// An array of int array. The sub-array at the i-th position signifies the
// grid axes the i-th loop will be sharded on.
- ShardingArray shardingArray = {};
+ llvm::SmallVectorWithFlagsFor<ShardingArray, 1> shardingArray = {};
FlatSymbolRefAttr grid = nullptr;
// `empty` being true indicates that no sharding information can be inferred
// at present. Note that it is different from the case where an operation is
// not sharded.
- bool empty = false;
+ bool getEmpty() const { return shardingArray.getFlag(0); }
+ bool setEmpty(bool Value) {
+ shardingArray.setFlag(0, Value);
+ return Value;
+ }
ShardingOption() = default;
ShardingOption(ShardingArray shardingArray, FlatSymbolRefAttr grid)
- : shardingArray(std::move(shardingArray)), grid(grid) {
+ : shardingArray(0, std::move(shardingArray)), grid(grid) {
assert(this->grid);
}
static ShardingOption makeEmpty() {
auto res = ShardingOption();
- res.empty = true;
+ res.setEmpty(true);
return res;
}
};
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Utils/Merger.h b/mlir/include/mlir/Dialect/SparseTensor/Utils/Merger.h
index b8d278152dc05..3d0eec4384745 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Utils/Merger.h
+++ b/mlir/include/mlir/Dialect/SparseTensor/Utils/Merger.h
@@ -18,6 +18,7 @@
#include "mlir/Dialect/SparseTensor/IR/SparseTensor.h"
#include "mlir/IR/Value.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <optional>
@@ -466,7 +467,7 @@ class Merger {
}
/// Sets whether the output tensor is sparse or not.
- void setHasSparseOut(bool s) { hasSparseOut = s; }
+ void setHasSparseOut(bool s) { latSets.setFlag(0, s); }
/// Establishes the two-way map that i <-> <t, lvl, lt>.
void setLoopDependentTensorLevel(LoopId i, TensorId t, Level lvl,
@@ -627,7 +628,6 @@ class Merger {
const TensorId syntheticTensor;
const unsigned numTensors;
const unsigned numLoops;
- bool hasSparseOut;
// Below we use `std::vector` for things which have a priori fixed
// sizes, whereas we use `llvm::SmallVector` for things with variable
@@ -662,7 +662,8 @@ class Merger {
llvm::SmallVector<TensorExp> tensorExps;
llvm::SmallVector<LatPoint> latPoints;
- llvm::SmallVector<SmallVector<LatPointId>> latSets;
+ // Flag bit 0 marks a sparse output tensor.
+ llvm::SmallVectorWithFlags<SmallVector<LatPointId>> latSets;
};
} // namespace sparse_tensor
diff --git a/mlir/include/mlir/Dialect/Tosa/Utils/ConversionUtils.h b/mlir/include/mlir/Dialect/Tosa/Utils/ConversionUtils.h
index 9f82efb802672..75ef5cbdc6686 100644
--- a/mlir/include/mlir/Dialect/Tosa/Utils/ConversionUtils.h
+++ b/mlir/include/mlir/Dialect/Tosa/Utils/ConversionUtils.h
@@ -129,7 +129,7 @@ TosaOp createOpAndInferShape(ImplicitLocOpBuilder &builder, Type resultTy,
// Compute the knowledge based on the inferred type.
auto inferredKnowledge = ValueKnowledge::getPessimisticValueState();
inferredKnowledge.dtype = mlir::cast<ShapedType>(resultTy).getElementType();
- inferredKnowledge.hasRank = predictedShape.hasRank();
+ inferredKnowledge.setHasRank(predictedShape.hasRank());
if (predictedShape.hasRank()) {
for (auto dim : predictedShape.getDims()) {
inferredKnowledge.sizes.push_back(dim);
@@ -139,7 +139,7 @@ TosaOp createOpAndInferShape(ImplicitLocOpBuilder &builder, Type resultTy,
// Compute the new type based on the joined version.
auto newKnowledge = ValueKnowledge::join(currentKnowledge, inferredKnowledge);
Type newTy =
- newKnowledge.hasRank
+ newKnowledge.hasRank()
? Type{mlir::RankedTensorType::get(llvm::ArrayRef(newKnowledge.sizes),
newKnowledge.dtype)}
: Type{mlir::UnrankedTensorType::get(newKnowledge.dtype)};
diff --git a/mlir/include/mlir/Dialect/Tosa/Utils/ShapeUtils.h b/mlir/include/mlir/Dialect/Tosa/Utils/ShapeUtils.h
index bdacb98710d33..e6a3392f992ae 100644
--- a/mlir/include/mlir/Dialect/Tosa/Utils/ShapeUtils.h
+++ b/mlir/include/mlir/Dialect/Tosa/Utils/ShapeUtils.h
@@ -17,7 +17,7 @@
#include "mlir/IR/Types.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#include "llvm/ADT/Sequence.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
namespace mlir {
namespace tosa {
@@ -33,20 +33,21 @@ namespace tosa {
struct ValueKnowledge {
ValueKnowledge() = delete;
ValueKnowledge(bool hasRank, llvm::ArrayRef<int64_t> newSizes, Type dtype)
- : hasError(false), hasRank(hasRank), dtype(dtype) {
+ : dtype(dtype) {
+ setHasRank(hasRank);
sizes.reserve(newSizes.size());
for (auto size : newSizes)
sizes.push_back(size);
}
- operator bool() const { return !hasError; }
+ operator bool() const { return !hasError(); }
// Get the static knowledge intrinsic to `type`.
static ValueKnowledge getKnowledgeFromType(Type type) {
ValueKnowledge result = getPessimisticValueState();
if (auto shapedType = dyn_cast<ShapedType>(type)) {
if (shapedType.hasRank()) {
- result.hasRank = true;
+ result.setHasRank(true);
result.sizes.reserve(shapedType.getRank());
for (auto dim : shapedType.getShape())
result.sizes.push_back(dim);
@@ -63,17 +64,19 @@ struct ValueKnowledge {
}
ShapedTypeComponents getShapedTypeComponents() const {
- return hasRank ? ShapedTypeComponents(sizes) : ShapedTypeComponents();
+ return hasRank() ? ShapedTypeComponents(sizes) : ShapedTypeComponents();
}
Type getType() const {
- if (hasRank)
+ if (hasRank())
return RankedTensorType::get(llvm::ArrayRef(sizes), dtype);
return UnrankedTensorType::get(dtype);
}
bool operator==(const ValueKnowledge &rhs) const {
- return hasRank == rhs.hasRank && sizes == rhs.sizes && dtype == rhs.dtype;
+ return hasRank() == rhs.hasRank() &&
+ ArrayRef<int64_t>(sizes) == ArrayRef<int64_t>(rhs.sizes) &&
+ dtype == rhs.dtype;
}
// Given two pieces of static knowledge, calculate conservatively the
@@ -84,33 +87,33 @@ struct ValueKnowledge {
// knowledge" default-initialized state to a state with more knowledge
// consistent with lhs and rhs.
ValueKnowledge result = getPessimisticValueState();
- result.hasError = true;
+ result.setHasError(true);
if (!lhs || !rhs || lhs.dtype != rhs.dtype)
return result;
- result.hasError = false;
+ result.setHasError(false);
result.dtype = lhs.dtype;
- if (!lhs.hasRank && !rhs.hasRank)
+ if (!lhs.hasRank() && !rhs.hasRank())
return result;
- if (!rhs.hasRank) {
- result.hasRank = true;
- result.sizes = lhs.sizes;
+ if (!rhs.hasRank()) {
+ result.setHasRank(true);
+ result.sizes.assign(lhs.sizes.begin(), lhs.sizes.end());
return result;
}
- if (!lhs.hasRank) {
- result.hasRank = true;
- result.sizes = rhs.sizes;
+ if (!lhs.hasRank()) {
+ result.setHasRank(true);
+ result.sizes.assign(rhs.sizes.begin(), rhs.sizes.end());
return result;
}
if (lhs.sizes.size() != rhs.sizes.size())
return result;
- result.hasRank = true;
+ result.setHasRank(true);
result.sizes.resize(lhs.sizes.size(), ShapedType::kDynamic);
for (auto i : llvm::seq<unsigned>(0, result.sizes.size())) {
int64_t lhsSize = lhs.sizes[i];
@@ -123,7 +126,7 @@ struct ValueKnowledge {
} else if (lhsSize == rhsSize) {
resultSize = lhsSize;
} else {
- result.hasError = true;
+ result.setHasError(true);
}
}
@@ -136,25 +139,25 @@ struct ValueKnowledge {
static ValueKnowledge meet(const ValueKnowledge &lhs,
const ValueKnowledge &rhs) {
ValueKnowledge result = getPessimisticValueState();
- result.hasError = true;
+ result.setHasError(true);
if (!lhs || !rhs || lhs.dtype != rhs.dtype)
return result;
- result.hasError = false;
+ result.setHasError(false);
result.dtype = lhs.dtype;
- if (!lhs.hasRank || !rhs.hasRank) {
- result.hasRank = false;
+ if (!lhs.hasRank() || !rhs.hasRank()) {
+ result.setHasRank(false);
return result;
}
if (lhs.sizes.size() != rhs.sizes.size()) {
- result.hasRank = false;
+ result.setHasRank(false);
return result;
}
- result.hasRank = true;
+ result.setHasRank(true);
result.sizes.resize(lhs.sizes.size(), ShapedType::kDynamic);
for (int i = 0, e = lhs.sizes.size(); i < e; i++) {
if (lhs.sizes[i] == rhs.sizes[i]) {
@@ -166,12 +169,17 @@ struct ValueKnowledge {
}
// Whether the value information has an error.
- bool hasError;
+ bool hasError() const { return sizes.getFlag(0); }
+ void setHasError(bool value) { sizes.setFlag(0, value); }
// Whether the value has known rank.
- bool hasRank;
+ bool hasRank() const { return sizes.getFlag(1); }
+ void setHasRank(bool value) { sizes.setFlag(1, value); }
// If `hasRank`, the sizes along each rank. Unknown sizes are represented as
// `ShapedType::kDynamic`.
- llvm::SmallVector<int64_t> sizes;
+ llvm::SmallVectorWithFlags<
+ int64_t, llvm::CalculateSmallVectorDefaultInlinedElements<int64_t>::value,
+ 2>
+ sizes;
// The dtype of a tensor.
// This is equal to nullptr if we don't know that it is a specific concrete
// type.
diff --git a/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.h b/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.h
index 8fe94ebcf658f..d6a963d4ebbbe 100644
--- a/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.h
+++ b/mlir/include/mlir/Dialect/Transform/IR/TransformDialect.h
@@ -14,6 +14,7 @@
#include "mlir/Support/LLVM.h"
#include "mlir/Support/TypeID.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include <optional>
@@ -129,7 +130,7 @@ class TransformDialectExtension
// Only load generated dialects if the user intends to apply
// transformations specified by the extension.
- if (!buildOnly)
+ if (!isBuildOnly())
for (const DialectLoader &loader : generatedDialectLoaders)
loader(context);
@@ -143,7 +144,8 @@ class TransformDialectExtension
/// Extension constructor. The argument indicates whether to skip generated
/// dialects when applying the extension.
explicit TransformDialectExtension(bool buildOnly = false)
- : buildOnly(buildOnly) {
+ : generatedDialectLoaders(
+ decltype(generatedDialectLoaders)::withFlags(unsigned(buildOnly))) {
static_cast<DerivedTy *>(this)->init();
}
@@ -254,10 +256,10 @@ class TransformDialectExtension
/// Callbacks loading the generated dialects, i.e. the dialects produced when
/// applying the transformations.
- SmallVector<DialectLoader> generatedDialectLoaders;
+ llvm::SmallVectorWithFlags<DialectLoader> generatedDialectLoaders;
/// Indicates that the extension is in build-only mode.
- bool buildOnly;
+ bool isBuildOnly() const { return generatedDialectLoaders.getFlag(0); }
};
template <typename OpTy>
diff --git a/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h b/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h
index 5bd71d68d253a..63af8ca16af3c 100644
--- a/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h
+++ b/mlir/include/mlir/ExecutionEngine/ExecutionEngine.h
@@ -14,6 +14,7 @@
#define MLIR_EXECUTIONENGINE_EXECUTIONENGINE_H_
#include "mlir/Support/LLVM.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
@@ -256,9 +257,10 @@ class ExecutionEngine {
/// Destroy functions in the libraries loaded by the ExecutionEngine that are
/// called when this ExecutionEngine is destructed.
- SmallVector<LibraryDestroyFn> destroyFns;
+ llvm::SmallVectorWithFlags<LibraryDestroyFn> destroyFns;
- bool isInitialized = false;
+ bool getIsInitialized() const { return destroyFns.getFlag(0); }
+ void setIsInitialized(bool Value) { destroyFns.setFlag(0, Value); }
};
} // namespace mlir
diff --git a/mlir/include/mlir/Interfaces/InferTypeOpInterface.h b/mlir/include/mlir/Interfaces/InferTypeOpInterface.h
index 1bfb66e681d8d..e89cc11978941 100644
--- a/mlir/include/mlir/Interfaces/InferTypeOpInterface.h
+++ b/mlir/include/mlir/Interfaces/InferTypeOpInterface.h
@@ -23,6 +23,8 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
+
namespace mlir {
class ShapedTypeComponents;
@@ -95,6 +97,9 @@ class ShapeAdaptor {
void dump() const;
private:
+ template <typename ShapeStorageT>
+ void getDimsImpl(ShapeStorageT &res) const;
+
// Union storing either ShapedTypeComponents, ShapedType (stored as Type and
// casted), or DenseIntElementsAttribute (stored as Atrtribute).
PointerUnion<ShapedTypeComponents *, Type, Attribute> val = nullptr;
@@ -110,45 +115,51 @@ class ShapeAdaptor {
/// Used by ShapedType type inferences.
class ShapedTypeComponents {
/// Internal storage type for shape.
- using ShapeStorageT = SmallVector<int64_t, 3>;
+ using ShapeStorageT = llvm::SmallVectorWithFlags<int64_t, 3>;
public:
/// Default construction is an unranked shape.
ShapedTypeComponents() : elementType(nullptr), attr(nullptr) {};
ShapedTypeComponents(Type elementType)
- : elementType(elementType), attr(nullptr), ranked(false) {}
+ : elementType(elementType), attr(nullptr) {}
ShapedTypeComponents(ShapedType shapedType) : attr(nullptr) {
- ranked = shapedType.hasRank();
+ dims.setFlag(0, shapedType.hasRank());
elementType = shapedType.getElementType();
- if (ranked)
- dims = llvm::to_vector<4>(shapedType.getShape());
+ if (hasRank()) {
+ ArrayRef<int64_t> shape = shapedType.getShape();
+ dims.assign(shape.begin(), shape.end());
+ }
}
ShapedTypeComponents(ShapeAdaptor adaptor) : attr(nullptr) {
- ranked = adaptor.hasRank();
+ dims.setFlag(0, adaptor.hasRank());
elementType = adaptor.getElementType();
- if (ranked)
+ if (hasRank())
adaptor.getDims(*this);
}
template <typename Arg, typename = std::enable_if_t<
std::is_constructible<ShapeStorageT, Arg>::value>>
ShapedTypeComponents(Arg &&arg, Type elementType = nullptr,
Attribute attr = nullptr)
- : dims(std::forward<Arg>(arg)), elementType(elementType), attr(attr),
- ranked(true) {}
+ : dims(std::forward<Arg>(arg)), elementType(elementType), attr(attr) {
+ dims.setFlag(0, true);
+ }
ShapedTypeComponents(ArrayRef<int64_t> vec, Type elementType = nullptr,
Attribute attr = nullptr)
- : dims(vec.begin(), vec.end()), elementType(elementType), attr(attr),
- ranked(true) {}
+ : dims(1, vec.begin(), vec.end()), elementType(elementType), attr(attr) {}
+
+ ShapedTypeComponents(SmallVectorImpl<int64_t> &&vec,
+ Type elementType = nullptr, Attribute attr = nullptr)
+ : dims(1, std::move(vec)), elementType(elementType), attr(attr) {}
/// Return the dimensions of the shape.
/// Requires: shape is ranked.
ArrayRef<int64_t> getDims() const {
- assert(ranked && "requires ranked shape");
+ assert(hasRank() && "requires ranked shape");
return dims;
}
/// Return whether the shape has a rank.
- bool hasRank() const { return ranked; };
+ bool hasRank() const { return dims.getFlag(0); };
/// Return the element type component.
Type getElementType() const { return elementType; };
@@ -162,7 +173,6 @@ class ShapedTypeComponents {
ShapeStorageT dims;
Type elementType;
Attribute attr;
- bool ranked{false};
};
/// Range of values and shapes (corresponding effectively to Shapes dialect's
diff --git a/mlir/include/mlir/Support/CyclicReplacerCache.h b/mlir/include/mlir/Support/CyclicReplacerCache.h
index 786bc49040d7e..dc14445eb4fc1 100644
--- a/mlir/include/mlir/Support/CyclicReplacerCache.h
+++ b/mlir/include/mlir/Support/CyclicReplacerCache.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <functional>
#include <optional>
#include <set>
@@ -139,19 +140,20 @@ class CyclicReplacerCache {
};
/// Every element currently in the progress of being replaced pushes a frame
/// onto this stack.
- llvm::SmallVector<ReplacementFrame> replacementStack;
+ llvm::SmallVectorWithFlags<ReplacementFrame> replacementStack;
/// Maps from each input element to its indices on the replacement stack.
llvm::DenseMap<InT, llvm::SmallVector<size_t, 2>> cyclicElementFrame;
/// If set to true, we are currently asking an element to break a cycle. No
/// more recursive invocations is allowed while this is true (the replacement
/// stack can no longer grow).
- bool resolvingCycle = false;
+ bool isResolvingCycle() const { return replacementStack.getFlag(0); }
+ void setResolvingCycle(bool value) { replacementStack.setFlag(0, value); }
};
template <typename InT, typename OutT>
typename CyclicReplacerCache<InT, OutT>::CacheEntry
CyclicReplacerCache<InT, OutT>::lookupOrInit(InT element) {
- assert(!resolvingCycle &&
+ assert(!isResolvingCycle() &&
"illegal recursive invocation while breaking cycle");
if (auto it = standaloneCache.find(element); it != standaloneCache.end())
@@ -168,9 +170,9 @@ CyclicReplacerCache<InT, OutT>::lookupOrInit(InT element) {
auto [it, inserted] = cyclicElementFrame.try_emplace(element);
if (!inserted) {
// This is a repeat of a known element. Try to break cycle here.
- resolvingCycle = true;
+ setResolvingCycle(true);
std::optional<OutT> result = cycleBreaker(element);
- resolvingCycle = false;
+ setResolvingCycle(false);
if (result) {
// Cycle was broken.
size_t dependentFrame = it->second.back();
diff --git a/mlir/include/mlir/TableGen/Class.h b/mlir/include/mlir/TableGen/Class.h
index e6bedc7cc896d..4451028b17f52 100644
--- a/mlir/include/mlir/TableGen/Class.h
+++ b/mlir/include/mlir/TableGen/Class.h
@@ -28,6 +28,7 @@
#include "mlir/TableGen/CodeGenHelpers.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
@@ -675,7 +676,8 @@ class Class {
template <typename NameT,
typename = std::enable_if_t<!std::is_same<NameT, Class>::value>>
Class(NameT &&name, bool isStruct = false)
- : className(stringify(std::forward<NameT>(name))), isStruct(isStruct) {}
+ : className(stringify(std::forward<NameT>(name))),
+ fields(decltype(fields)::withFlags(unsigned(isStruct))) {}
/// Add a new constructor to this class and prune and constructors made
/// redundant by it. Returns null if the constructor was not added. Else,
@@ -886,9 +888,10 @@ class Class {
/// The pending list of methods and constructors.
std::vector<std::unique_ptr<Method>> methods;
/// The pending list of private class fields.
- SmallVector<Field> fields;
+ // Flag bit 0 selects a struct declaration.
+ llvm::SmallVectorWithFlags<Field> fields;
/// Whether this is a `class` or a `struct`.
- bool isStruct;
+ bool isStructDeclaration() const { return fields.getFlag(0); }
/// A list of declarations in the class, emitted in order.
std::vector<std::unique_ptr<ClassDeclaration>> declarations;
diff --git a/mlir/include/mlir/TableGen/Operator.h b/mlir/include/mlir/TableGen/Operator.h
index bb36c077708e9..1d9b251de91b3 100644
--- a/mlir/include/mlir/TableGen/Operator.h
+++ b/mlir/include/mlir/TableGen/Operator.h
@@ -25,6 +25,7 @@
#include "mlir/TableGen/Type.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/SMLoc.h"
@@ -335,7 +336,7 @@ class Operator {
void print(llvm::raw_ostream &os) const;
/// Return whether all the result types are known.
- bool allResultTypesKnown() const { return allResultsHaveKnownTypes; };
+ bool allResultTypesKnown() const { return builders.getFlag(0); };
/// Return all arguments or type constraints with same type as result[index].
/// Requires: all result types are known.
@@ -428,7 +429,8 @@ class Operator {
SmallVector<OperandAttrOrProp, 4> attrPropOrOperandMapping;
/// The builders of this operator.
- SmallVector<Builder> builders;
+ // Flag bit 0 records whether every result type can be inferred.
+ llvm::SmallVectorWithFlags<Builder> builders;
/// The number of native attributes stored in the leading positions of
/// `attributes`.
@@ -436,9 +438,6 @@ class Operator {
/// The TableGen definition of this op.
const llvm::Record &def;
-
- /// Whether the type of all results are known.
- bool allResultsHaveKnownTypes;
};
} // namespace tblgen
diff --git a/mlir/include/mlir/Tools/PDLL/ODS/Operation.h b/mlir/include/mlir/Tools/PDLL/ODS/Operation.h
index e49db88ef9c93..0933eff9d00f2 100644
--- a/mlir/include/mlir/Tools/PDLL/ODS/Operation.h
+++ b/mlir/include/mlir/Tools/PDLL/ODS/Operation.h
@@ -9,6 +9,7 @@
#ifndef MLIR_TOOLS_PDLL_ODS_OPERATION_H_
#define MLIR_TOOLS_PDLL_ODS_OPERATION_H_
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include <string>
#include "mlir/Support/LLVM.h"
@@ -168,7 +169,7 @@ class Operation {
ArrayRef<OperandOrResult> getResults() const { return results; }
/// Return if the operation is known to support result type inferrence.
- bool hasResultTypeInferrence() const { return supportsTypeInferrence; }
+ bool hasResultTypeInferrence() const { return getSupportsTypeInferrence(); }
private:
Operation(StringRef name, StringRef summary, StringRef desc,
@@ -185,7 +186,8 @@ class Operation {
std::string nativeClassName;
/// Flag indicating if the operation is known to support type inferrence.
- bool supportsTypeInferrence;
+ bool getSupportsTypeInferrence() const { return attributes.getFlag(0); }
+ void setSupportsTypeInferrence(bool Value) { attributes.setFlag(0, Value); }
/// The source location of this operation.
SMRange location;
@@ -197,7 +199,7 @@ class Operation {
SmallVector<OperandOrResult> results;
/// The attributes of the operation.
- SmallVector<Attribute> attributes;
+ llvm::SmallVectorWithFlags<Attribute> attributes;
/// Allow access to the private constructor.
friend class Dialect;
diff --git a/mlir/lib/Analysis/Presburger/Simplex.cpp b/mlir/lib/Analysis/Presburger/Simplex.cpp
index f2e6f83e99e57..0db359360060d 100644
--- a/mlir/lib/Analysis/Presburger/Simplex.cpp
+++ b/mlir/lib/Analysis/Presburger/Simplex.cpp
@@ -48,8 +48,8 @@ scaleAndAddForAssert(ArrayRef<DynamicAPInt> a, const DynamicAPInt &scale,
}
SimplexBase::SimplexBase(unsigned nVar, bool mustUseBigM)
- : usingBigM(mustUseBigM), nRedundant(0), nSymbol(0),
- tableau(0, getNumFixedCols() + nVar), empty(false) {
+ : nRedundant(0), nSymbol(0), tableau(0, (mustUseBigM ? 3u : 2u) + nVar),
+ var(decltype(this->var)::withFlags(unsigned(mustUseBigM))) {
var.reserve(nVar);
colUnknown.reserve(nVar + 1);
colUnknown.insert(colUnknown.begin(), getNumFixedCols(), nullIndex);
@@ -127,7 +127,7 @@ unsigned SimplexBase::addRow(ArrayRef<DynamicAPInt> coeffs,
unsigned newRow = addZeroRow(makeRestricted);
tableau(newRow, 1) = coeffs.back();
- if (usingBigM) {
+ if (getUsingBigM()) {
// When the lexicographic pivot rule is used, instead of the variables
//
// x, y, z ...
@@ -564,7 +564,7 @@ SymbolicLexOpt SymbolicLexSimplex::computeSymbolicIntegerLexMin() {
while (level > 0) {
assert(level >= stack.size());
if (level > stack.size()) {
- if (empty || domainSimplex.findIntegerLexMin().isEmpty()) {
+ if (getEmpty() || domainSimplex.findIntegerLexMin().isEmpty()) {
// No integer points; return.
--level;
continue;
@@ -703,7 +703,7 @@ std::optional<unsigned> LexSimplex::maybeGetViolatedRow() const {
/// orientation, which always succeeds unless the constraints have no solution
/// in which case we just give up and return.
LogicalResult LexSimplex::restoreRationalConsistency() {
- if (empty)
+ if (getEmpty())
return failure();
while (std::optional<unsigned> maybeViolatedRow = maybeGetViolatedRow())
if (moveRowUnknownToColumn(*maybeViolatedRow).failed())
@@ -1066,7 +1066,7 @@ std::optional<unsigned> Simplex::findPivotRow(std::optional<unsigned> skipRow,
return retRow;
}
-bool SimplexBase::isEmpty() const { return empty; }
+bool SimplexBase::isEmpty() const { return getEmpty(); }
void SimplexBase::swapRows(unsigned i, unsigned j) {
if (i == j)
@@ -1093,10 +1093,10 @@ void SimplexBase::markEmpty() {
// If the set is already empty, then we shouldn't add another UnmarkEmpty log
// entry, since in that case the Simplex will be erroneously marked as
// non-empty when rolling back past this point.
- if (empty)
+ if (getEmpty())
return;
undoLog.emplace_back(UndoLogEntry::UnmarkEmpty);
- empty = true;
+ setEmpty(true);
}
/// Add an inequality to the tableau. If coeffs is c_0, c_1, ... c_n, where n
@@ -1253,7 +1253,7 @@ void SimplexBase::undo(UndoLogEntry entry) {
var.pop_back();
colUnknown.pop_back();
} else if (entry == UndoLogEntry::UnmarkEmpty) {
- empty = false;
+ setEmpty(false);
} else if (entry == UndoLogEntry::UnmarkLastRedundant) {
nRedundant--;
} else if (entry == UndoLogEntry::RestoreBasis) {
@@ -1362,7 +1362,7 @@ MaybeOptimum<Fraction> Simplex::computeRowOptimum(Direction direction,
/// or std::nullopt if it is unbounded.
MaybeOptimum<Fraction> Simplex::computeOptimum(Direction direction,
ArrayRef<DynamicAPInt> coeffs) {
- if (empty)
+ if (getEmpty())
return OptimumKind::Empty;
SimplexRollbackScopeExit scopeExit(*this);
@@ -1373,7 +1373,7 @@ MaybeOptimum<Fraction> Simplex::computeOptimum(Direction direction,
MaybeOptimum<Fraction> Simplex::computeOptimum(Direction direction,
Unknown &u) {
- if (empty)
+ if (getEmpty())
return OptimumKind::Empty;
if (u.orientation == Orientation::Column) {
unsigned column = u.pos;
@@ -1396,8 +1396,9 @@ MaybeOptimum<Fraction> Simplex::computeOptimum(Direction direction,
}
bool Simplex::isBoundedAlongConstraint(unsigned constraintIndex) {
- assert(!empty && "It is not meaningful to ask whether a direction is bounded "
- "in an empty set.");
+ assert(!getEmpty() &&
+ "It is not meaningful to ask whether a direction is bounded "
+ "in an empty set.");
// The constraint's perpendicular is already bounded below, since it is a
// constraint. If it is also bounded above, we can return true.
return computeOptimum(Direction::Up, con[constraintIndex]).isBounded();
@@ -1428,7 +1429,7 @@ void Simplex::markRowRedundant(Unknown &u) {
void Simplex::detectRedundant(unsigned offset, unsigned count) {
assert(offset + count <= con.size() && "invalid range!");
// It is not meaningful to talk about redundancy for empty sets.
- if (empty)
+ if (getEmpty())
return;
// Iterate through the constraints and check for each one if it can attain
@@ -1468,7 +1469,7 @@ void Simplex::detectRedundant(unsigned offset, unsigned count) {
}
bool Simplex::isUnbounded() {
- if (empty)
+ if (getEmpty())
return false;
SmallVector<DynamicAPInt, 8> dir(var.size() + 1);
@@ -1501,7 +1502,7 @@ Simplex Simplex::makeProduct(const Simplex &a, const Simplex &b) {
Simplex result(numVar);
result.tableau.reserveRows(numCon);
- result.empty = a.empty || b.empty;
+ result.setEmpty(a.getEmpty() || b.getEmpty());
auto concat = [](ArrayRef<Unknown> v, ArrayRef<Unknown> w) {
SmallVector<Unknown, 8> result;
@@ -1511,7 +1512,7 @@ Simplex Simplex::makeProduct(const Simplex &a, const Simplex &b) {
return result;
};
result.con = concat(a.con, b.con);
- result.var = concat(a.var, b.var);
+ result.var.assign(concat(a.var, b.var));
auto indexFromBIndex = [&](int index) {
return index >= 0 ? a.getNumVariables() + index
@@ -1568,7 +1569,7 @@ Simplex Simplex::makeProduct(const Simplex &a, const Simplex &b) {
}
std::optional<SmallVector<Fraction, 8>> Simplex::getRationalSample() const {
- if (empty)
+ if (getEmpty())
return {};
SmallVector<Fraction, 8> sample;
@@ -1593,7 +1594,7 @@ void LexSimplexBase::addInequality(ArrayRef<DynamicAPInt> coeffs) {
}
MaybeOptimum<SmallVector<Fraction, 8>> LexSimplex::getRationalSample() const {
- if (empty)
+ if (getEmpty())
return OptimumKind::Empty;
SmallVector<Fraction, 8> sample;
@@ -1614,7 +1615,7 @@ MaybeOptimum<SmallVector<Fraction, 8>> LexSimplex::getRationalSample() const {
// If the variable is in row position, its sample value is the
// entry in the constant column divided by the denominator.
DynamicAPInt denom = tableau(u.pos, 0);
- if (usingBigM)
+ if (getUsingBigM())
if (tableau(u.pos, 2) != denom)
return OptimumKind::Unbounded;
sample.emplace_back(tableau(u.pos, 1), denom);
@@ -1625,7 +1626,7 @@ MaybeOptimum<SmallVector<Fraction, 8>> LexSimplex::getRationalSample() const {
std::optional<SmallVector<DynamicAPInt, 8>>
Simplex::getSamplePointIfIntegral() const {
// If the tableau is empty, no sample point exists.
- if (empty)
+ if (getEmpty())
return {};
// The value will always exist since the Simplex is non-empty.
@@ -1994,7 +1995,7 @@ void Simplex::reduceBasis(IntMatrix &basis, unsigned level) {
/// To avoid potentially arbitrarily large recursion depths leading to stack
/// overflows, this algorithm is implemented iteratively.
std::optional<SmallVector<DynamicAPInt, 8>> Simplex::findIntegerSample() {
- if (empty)
+ if (getEmpty())
return {};
unsigned nDims = var.size();
@@ -2127,7 +2128,7 @@ bool Simplex::isFlatAlong(ArrayRef<DynamicAPInt> coeffs) {
void SimplexBase::print(raw_ostream &os) const {
os << "rows = " << getNumRows() << ", columns = " << getNumColumns() << "\n";
- if (empty)
+ if (getEmpty())
os << "Simplex marked empty!\n";
os << "var: ";
for (unsigned i = 0; i < var.size(); ++i) {
@@ -2214,7 +2215,7 @@ Simplex::IneqType Simplex::findIneqType(ArrayRef<DynamicAPInt> coeffs) {
/// Checks whether the type of the inequality with coefficients `coeffs`
/// is Redundant.
bool Simplex::isRedundantInequality(ArrayRef<DynamicAPInt> coeffs) {
- assert(!empty &&
+ assert(!getEmpty() &&
"It is not meaningful to ask about redundancy in an empty set!");
return findIneqType(coeffs) == IneqType::Redundant;
}
@@ -2224,7 +2225,7 @@ bool Simplex::isRedundantInequality(ArrayRef<DynamicAPInt> coeffs) {
/// always zero under the existing constraints. `coeffs` is always zero
/// when the minimum and maximum value that `coeffs` can take are both zero.
bool Simplex::isRedundantEquality(ArrayRef<DynamicAPInt> coeffs) {
- assert(!empty &&
+ assert(!getEmpty() &&
"It is not meaningful to ask about redundancy in an empty set!");
MaybeOptimum<Fraction> minimum = computeOptimum(Direction::Down, coeffs);
MaybeOptimum<Fraction> maximum = computeOptimum(Direction::Up, coeffs);
diff --git a/mlir/lib/AsmParser/AffineParser.cpp b/mlir/lib/AsmParser/AffineParser.cpp
index 405970d4fb15e..99d0c4fad02d2 100644
--- a/mlir/lib/AsmParser/AffineParser.cpp
+++ b/mlir/lib/AsmParser/AffineParser.cpp
@@ -19,6 +19,7 @@
#include "mlir/IR/IntegerSet.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/Support/LLVM.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
@@ -64,8 +65,9 @@ class AffineParser : public Parser {
nullptr,
function_ref<void(bool, OpAsmParser::UnresolvedOperand)> addOperand =
nullptr)
- : Parser(state), allowParsingSSAIds(allowParsingSSAIds),
- parseElement(parseElement), addOperand(addOperand) {}
+ : Parser(state), parseElement(parseElement), addOperand(addOperand),
+ dimsAndSymbols(decltype(this->dimsAndSymbols)::withFlags(
+ unsigned(allowParsingSSAIds))) {}
ParseResult parseAffineMapRange(unsigned numDims, unsigned numSymbols,
AffineMap &result);
@@ -110,12 +112,14 @@ class AffineParser : public Parser {
AffineExpr parseAffineConstraint(bool *isEq);
private:
- bool allowParsingSSAIds;
+ bool getAllowParsingSSAIds() const { return dimsAndSymbols.getFlag(0); }
+ void setAllowParsingSSAIds(bool Value) { dimsAndSymbols.setFlag(0, Value); }
function_ref<FailureOr<OpAsmParser::UnresolvedOperand>()> parseElement;
function_ref<void(bool, OpAsmParser::UnresolvedOperand)> addOperand;
unsigned numDimOperands = 0;
unsigned numSymbolOperands = 0;
- SmallVector<std::pair<std::pair<StringRef, unsigned>, AffineExpr>, 4>
+ llvm::SmallVectorWithFlags<
+ std::pair<std::pair<StringRef, unsigned>, AffineExpr>, 4>
dimsAndSymbols;
};
} // namespace
@@ -313,7 +317,7 @@ AffineExpr AffineParser::parseBareIdExpr() {
/// Parse an SSA id which may appear in an affine expression.
AffineExpr AffineParser::parseSSAIdExpr(bool isSymbol) {
- if (!allowParsingSSAIds)
+ if (!getAllowParsingSSAIds())
return emitWrongTokenError("unexpected ssa identifier"), nullptr;
if (getToken().isNot(Token::percent_identifier))
return emitWrongTokenError("expected ssa identifier"), nullptr;
diff --git a/mlir/lib/Bytecode/Reader/BytecodeReader.cpp b/mlir/lib/Bytecode/Reader/BytecodeReader.cpp
index 6634d1d784a1e..7438dcaa41193 100644
--- a/mlir/lib/Bytecode/Reader/BytecodeReader.cpp
+++ b/mlir/lib/Bytecode/Reader/BytecodeReader.cpp
@@ -891,20 +891,24 @@ class AttrTypeReader {
LogicalResult readAttribute(uint64_t index, Attribute &result,
uint64_t depth = 0) {
- return readEntry(attributes, index, result, "attribute", depth);
+ return readEntry(MutableArrayRef(attributes.data(), attributes.size()),
+ index, result, "attribute", depth);
}
LogicalResult readType(uint64_t index, Type &result, uint64_t depth = 0) {
- return readEntry(types, index, result, "type", depth);
+ return readEntry(MutableArrayRef(types.data(), types.size()), index, result,
+ "type", depth);
}
/// Resolve the attribute or type at the given index. Returns nullptr on
/// failure.
Attribute resolveAttribute(size_t index, uint64_t depth = 0) {
- return resolveEntry(attributes, index, "Attribute", depth);
+ return resolveEntry(MutableArrayRef(attributes.data(), attributes.size()),
+ index, "Attribute", depth);
}
Type resolveType(size_t index, uint64_t depth = 0) {
- return resolveEntry(types, index, "Type", depth);
+ return resolveEntry(MutableArrayRef(types.data(), types.size()), index,
+ "Type", depth);
}
Attribute getAttributeOrSentinel(size_t index) {
@@ -966,18 +970,18 @@ class AttrTypeReader {
}
/// Whether currently resolving.
- bool isResolving() const { return resolving; }
+ bool isResolving() const { return getResolving(); }
private:
/// Resolve the given entry at `index`.
template <typename T>
- T resolveEntry(SmallVectorImpl<Entry<T>> &entries, uint64_t index,
+ T resolveEntry(MutableArrayRef<Entry<T>> entries, uint64_t index,
StringRef entryType, uint64_t depth = 0);
/// Read the entry at the given index, returning failure if the entry is not
/// yet resolved.
template <typename T>
- LogicalResult readEntry(SmallVectorImpl<Entry<T>> &entries, uint64_t index,
+ LogicalResult readEntry(MutableArrayRef<Entry<T>> entries, uint64_t index,
T &result, StringRef entryType, uint64_t depth);
/// Parse an entry using the given reader that was encoded using a custom
@@ -1007,7 +1011,7 @@ class AttrTypeReader {
/// The set of attribute and type entries.
SmallVector<AttrEntry> attributes;
- SmallVector<TypeEntry> types;
+ llvm::SmallVectorWithFlags<TypeEntry> types;
/// A location used for error emission.
Location fileLoc;
@@ -1025,7 +1029,8 @@ class AttrTypeReader {
std::vector<std::pair<uint64_t, EntryKind>> deferredWorklist;
/// Flag indicating if we are currently resolving an attribute or type.
- bool resolving = false;
+ bool getResolving() const { return types.getFlag(0); }
+ void setResolving(bool Value) { types.setFlag(0, Value); }
};
class DialectReader : public DialectBytecodeReader {
@@ -1357,7 +1362,9 @@ LogicalResult AttrTypeReader::initialize(
};
// Process each of the attributes, and then the types.
- if (failed(parseEntries(attributes)) || failed(parseEntries(types)))
+ if (failed(parseEntries(
+ MutableArrayRef(attributes.data(), attributes.size()))) ||
+ failed(parseEntries(MutableArrayRef(types.data(), types.size()))))
return failure();
// Ensure that we read everything from the section.
@@ -1370,12 +1377,12 @@ LogicalResult AttrTypeReader::initialize(
}
template <typename T>
-T AttrTypeReader::resolveEntry(SmallVectorImpl<Entry<T>> &entries,
+T AttrTypeReader::resolveEntry(MutableArrayRef<Entry<T>> entries,
uint64_t index, StringRef entryType,
uint64_t depth) {
- bool oldResolving = resolving;
- resolving = true;
- llvm::scope_exit restoreResolving([&]() { resolving = oldResolving; });
+ bool oldResolving = getResolving();
+ setResolving(true);
+ llvm::scope_exit restoreResolving([&]() { setResolving(oldResolving); });
if (index >= entries.size()) {
emitError(fileLoc) << "invalid " << entryType << " index: " << index;
@@ -1460,7 +1467,7 @@ T AttrTypeReader::resolveEntry(SmallVectorImpl<Entry<T>> &entries,
}
template <typename T>
-LogicalResult AttrTypeReader::readEntry(SmallVectorImpl<Entry<T>> &entries,
+LogicalResult AttrTypeReader::readEntry(MutableArrayRef<Entry<T>> entries,
uint64_t index, T &result,
StringRef entryType, uint64_t depth) {
if (index >= entries.size())
@@ -1595,9 +1602,10 @@ class mlir::BytecodeReader::Impl {
Impl(Location fileLoc, const ParserConfig &config, bool lazyLoading,
llvm::MemoryBufferRef buffer,
const std::shared_ptr<llvm::SourceMgr> &bufferOwnerRef)
- : config(config), fileLoc(fileLoc), lazyLoading(lazyLoading),
+ : config(config), fileLoc(fileLoc),
attrTypeReader(stringReader, resourceReader, dialectsMap, version,
fileLoc, config),
+ dialects(decltype(this->dialects)::withFlags(unsigned(lazyLoading))),
// Use the builtin unrealized conversion cast operation to represent
// forward references to values that aren't yet defined.
forwardRefOpState(UnknownLoc::get(config.getContext()),
@@ -1745,7 +1753,8 @@ class mlir::BytecodeReader::Impl {
RegionReadState(MutableArrayRef<Region> regions, EncodingReader *reader,
bool isIsolatedFromAbove)
: curRegion(regions.begin()), endRegion(regions.end()), reader(reader),
- isIsolatedFromAbove(isIsolatedFromAbove) {}
+ curBlocks(decltype(this->curBlocks)::withFlags(
+ unsigned(isIsolatedFromAbove))) {}
/// The current regions being read.
MutableArrayRef<Region>::iterator curRegion, endRegion;
@@ -1760,7 +1769,7 @@ class mlir::BytecodeReader::Impl {
unsigned numValues = 0;
/// The current blocks of the region being read.
- SmallVector<Block *> curBlocks;
+ llvm::SmallVectorWithFlags<Block *> curBlocks;
Region::iterator curBlock = {};
/// The number of operations remaining to be read from the current block
@@ -1768,7 +1777,8 @@ class mlir::BytecodeReader::Impl {
uint64_t numOpsRemaining = 0;
/// A flag indicating if the regions being read are isolated from above.
- bool isIsolatedFromAbove = false;
+ bool getIsIsolatedFromAbove() const { return curBlocks.getFlag(0); }
+ void setIsIsolatedFromAbove(bool Value) { curBlocks.setFlag(0, Value); }
};
LogicalResult parseIRSection(ArrayRef<uint8_t> sectionData, Block *block);
@@ -1867,7 +1877,8 @@ class mlir::BytecodeReader::Impl {
Location fileLoc;
/// Flag that indicates if lazyloading is enabled.
- bool lazyLoading;
+ bool getLazyLoading() const { return dialects.getFlag(0); }
+ void setLazyLoading(bool Value) { dialects.setFlag(0, Value); }
/// Keep track of operations that have been lazy loaded (their regions haven't
/// been materialized), along with the `RegionReadState` that allows to
@@ -1886,7 +1897,7 @@ class mlir::BytecodeReader::Impl {
StringRef producer;
/// The table of IR units referenced within the bytecode file.
- SmallVector<std::unique_ptr<BytecodeDialect>> dialects;
+ llvm::SmallVectorWithFlags<std::unique_ptr<BytecodeDialect>> dialects;
llvm::StringMap<BytecodeDialect *> dialectsMap;
SmallVector<BytecodeOperationName> opNames;
@@ -2033,7 +2044,7 @@ LogicalResult BytecodeReader::Impl::parseVersion(EncodingReader &reader) {
}
// Override any request to lazy-load if the bytecode version is too old.
if (version < bytecode::kLazyLoading)
- lazyLoading = false;
+ setLazyLoading(false);
return success();
}
@@ -2514,7 +2525,8 @@ BytecodeReader::Impl::parseRegions(std::vector<RegionReadState> ®ionStack,
// If the user has a callback set, they have the opportunity to
// control lazyloading as we go.
- if (lazyLoading && (!lazyOpsCallback || !lazyOpsCallback(*op))) {
+ if (getLazyLoading() &&
+ (!lazyOpsCallback || !lazyOpsCallback(*op))) {
lazyLoadableOps.emplace_back(*op, std::move(childState));
lazyLoadableOpsMap.try_emplace(*op,
std::prev(lazyLoadableOps.end()));
@@ -2544,7 +2556,7 @@ BytecodeReader::Impl::parseRegions(std::vector<RegionReadState> ®ionStack,
// When the regions have been fully parsed, pop them off of the read stack. If
// the regions were isolated from above, we also pop the last value scope.
- if (readState.isIsolatedFromAbove) {
+ if (readState.getIsIsolatedFromAbove()) {
assert(!valueScopes.empty() && "Expect a valueScope after reading region");
valueScopes.pop_back();
}
diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
index e39b20492e5ed..05179e2e1a4c9 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
@@ -482,8 +482,8 @@ void BufferizationOptions::setFunctionBoundaryTypeConversion(
// If not builtin, fallback to unknown type conversion.
return options.unknownTypeConverterFn(type, memorySpace, options);
};
- inferFunctionResultLayout =
- layoutMapOption == LayoutMapOption::InferLayoutMap;
+ setInferFunctionResultLayout(layoutMapOption ==
+ LayoutMapOption::InferLayoutMap);
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/Bufferization/Transforms/OneShotModuleBufferize.cpp b/mlir/lib/Dialect/Bufferization/Transforms/OneShotModuleBufferize.cpp
index 41d9a37844c9a..22048c43f2f77 100644
--- a/mlir/lib/Dialect/Bufferization/Transforms/OneShotModuleBufferize.cpp
+++ b/mlir/lib/Dialect/Bufferization/Transforms/OneShotModuleBufferize.cpp
@@ -590,7 +590,7 @@ LogicalResult mlir::bufferization::bufferizeModuleOp(
}
// Change buffer return types to more precise layout maps.
- if (options.inferFunctionResultLayout)
+ if (options.getInferFunctionResultLayout())
foldMemRefCasts(funcOp);
}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp b/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
index 64cec0eadd2cb..799f301ef9973 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/BasicPtxBuilderInterface.cpp
@@ -161,7 +161,7 @@ LogicalResult PtxBuilder::insertValue(Value v, PTXRegisterMod itype) {
}
if (itype == PTXRegisterMod::ReadWrite)
ptxOperands.push_back(v);
- hasResult = true;
+ setHasResult(true);
};
llvm::raw_string_ostream ss(registerConstraints);
@@ -198,10 +198,9 @@ LogicalResult PtxBuilder::insertValue(Value v, PTXRegisterMod itype) {
}
/// Check if the operation needs to pack and unpack results.
-static bool
-needsPackUnpack(BasicPtxBuilderInterface interfaceOp,
- bool needsManualRegisterMapping,
- SmallVectorImpl<PTXRegisterMod> ®isterModifiers) {
+static bool needsPackUnpack(BasicPtxBuilderInterface interfaceOp,
+ bool needsManualRegisterMapping,
+ ArrayRef<PTXRegisterMod> registerModifiers) {
if (needsManualRegisterMapping)
return false;
const unsigned writeOnlyVals = interfaceOp->getNumResults();
@@ -215,11 +214,9 @@ needsPackUnpack(BasicPtxBuilderInterface interfaceOp,
/// Pack the result types of the interface operation.
/// If the operation has multiple results, it packs them into a struct
/// type. Otherwise, it returns the original result types.
-static SmallVector<Type>
-packResultTypes(BasicPtxBuilderInterface interfaceOp,
- bool needsManualRegisterMapping,
- SmallVectorImpl<PTXRegisterMod> ®isterModifiers,
- SmallVectorImpl<Value> &ptxOperands) {
+static SmallVector<Type> packResultTypes(
+ BasicPtxBuilderInterface interfaceOp, bool needsManualRegisterMapping,
+ ArrayRef<PTXRegisterMod> registerModifiers, ArrayRef<Value> ptxOperands) {
MLIRContext *ctx = interfaceOp->getContext();
TypeRange resultRange = interfaceOp->getResultTypes();
@@ -452,8 +449,9 @@ LLVM::InlineAsmOp PtxBuilder::build() {
auto asmDialectAttr = LLVM::AsmDialectAttr::get(interfaceOp->getContext(),
LLVM::AsmDialect::AD_ATT);
- SmallVector<Type> resultTypes = packResultTypes(
- interfaceOp, needsManualRegisterMapping, registerModifiers, ptxOperands);
+ SmallVector<Type> resultTypes =
+ packResultTypes(interfaceOp, getNeedsManualRegisterMapping(),
+ registerModifiers, ptxOperands);
// Remove the last comma from the constraints string.
if (!registerConstraints.empty() &&
@@ -462,7 +460,7 @@ LLVM::InlineAsmOp PtxBuilder::build() {
registerConstraints = canonicalizeRegisterConstraints(registerConstraints);
std::string ptxInstruction = interfaceOp.getPtx();
- if (!needsManualRegisterMapping)
+ if (!getNeedsManualRegisterMapping())
ptxInstruction = rewriteAsmPlaceholders(ptxInstruction);
// Add the predicate to the asm string.
@@ -515,18 +513,18 @@ void PtxBuilder::buildAndReplaceOp() {
LDBG() << "\n Generated PTX \n\t" << inlineAsmOp;
// Case 0: no result at all → just erase wrapper op.
- if (!hasResult) {
+ if (!getHasResult()) {
rewriter.eraseOp(interfaceOp);
return;
}
- if (needsManualRegisterMapping) {
+ if (getNeedsManualRegisterMapping()) {
rewriter.replaceOp(interfaceOp, inlineAsmOp->getResults());
return;
}
// Case 1: Simple path, single scalar inline asm result.
- if (!needsPackUnpack(interfaceOp, needsManualRegisterMapping,
+ if (!needsPackUnpack(interfaceOp, getNeedsManualRegisterMapping(),
registerModifiers)) {
// Sub-case 1a: the wrapper op has a declared result -- replace it
// directly with the inline asm result.
diff --git a/mlir/lib/Dialect/Linalg/Transforms/BlockPackMatmul.cpp b/mlir/lib/Dialect/Linalg/Transforms/BlockPackMatmul.cpp
index 99a7de99619dc..78c64fc53e5ec 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/BlockPackMatmul.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/BlockPackMatmul.cpp
@@ -173,7 +173,7 @@ linalg::blockPackMatmul(RewriterBase &rewriter, linalg::LinalgOp linalgOp,
// Scalable tile sizes are non-constant at compile time, so they can never
// satisfy the full-tile divisibility check. Reject early before creating
// any ops to avoid modifying IR before returning notifyMatchFailure.
- if (!options->allowPadding && hasScalable)
+ if (!options->getAllowPadding() && hasScalable)
return rewriter.notifyMatchFailure(
linalgOp, "scalable block factors require padding");
@@ -194,7 +194,7 @@ linalg::blockPackMatmul(RewriterBase &rewriter, linalg::LinalgOp linalgOp,
}
// If padding is disabled, make sure that dimensions can be packed cleanly.
- if (!options->allowPadding &&
+ if (!options->getAllowPadding() &&
!validateFullTilesOnDims(linalgOp, mnkTiles, options->mnkOrder)) {
return rewriter.notifyMatchFailure(linalgOp,
"expect packing full tiles only");
@@ -231,8 +231,8 @@ linalg::blockPackMatmul(RewriterBase &rewriter, linalg::LinalgOp linalgOp,
// Transpose LHS matrix according to the options.
FailureOr<PackTransposeResult> packedLhs = transposePackedMatmul(
rewriter, packedMatmul->packedLinalgOp, packedMatmul->packOps[0], maps[0],
- contractDims->m, options->lhsTransposeOuterBlocks,
- options->lhsTransposeInnerBlocks);
+ contractDims->m, options->getLhsTransposeOuterBlocks(),
+ options->getLhsTransposeInnerBlocks());
if (failed(packedLhs))
return failure();
@@ -243,8 +243,8 @@ linalg::blockPackMatmul(RewriterBase &rewriter, linalg::LinalgOp linalgOp,
// Transpose RHS matrix according to the options.
FailureOr<PackTransposeResult> packedRhs = transposePackedMatmul(
rewriter, packedMatmul->packedLinalgOp, packedMatmul->packOps[1], maps[1],
- contractDims->k, options->rhsTransposeOuterBlocks,
- options->rhsTransposeInnerBlocks);
+ contractDims->k, options->getRhsTransposeOuterBlocks(),
+ options->getRhsTransposeInnerBlocks());
if (failed(packedRhs))
return failure();
@@ -351,15 +351,15 @@ struct LinalgBlockPackMatmul
if (llvm::none_of(options.scalableBlockFactors, [](bool b) { return b; }))
options.scalableBlockFactors.clear();
- options.allowPadding = allowPadding;
- options.mnkPaddedSizesNextMultipleOf =
- SmallVector<int64_t>{*mnkPaddedSizesNextMultipleOf};
+ options.setAllowPadding(allowPadding);
+ options.mnkPaddedSizesNextMultipleOf.assign(
+ SmallVector<int64_t>{*mnkPaddedSizesNextMultipleOf});
if (!mnkOrder.empty())
options.mnkOrder = SmallVector<int64_t>{*mnkOrder};
- options.lhsTransposeOuterBlocks = lhsTransposeOuterBlocks;
- options.lhsTransposeInnerBlocks = lhsTransposeInnerBlocks;
- options.rhsTransposeOuterBlocks = rhsTransposeOuterBlocks;
- options.rhsTransposeInnerBlocks = rhsTransposeInnerBlocks;
+ options.setLhsTransposeOuterBlocks(lhsTransposeOuterBlocks);
+ options.setLhsTransposeInnerBlocks(lhsTransposeInnerBlocks);
+ options.setRhsTransposeOuterBlocks(rhsTransposeOuterBlocks);
+ options.setRhsTransposeInnerBlocks(rhsTransposeInnerBlocks);
return options;
};
diff --git a/mlir/lib/Dialect/Linalg/Transforms/PadTilingInterface.cpp b/mlir/lib/Dialect/Linalg/Transforms/PadTilingInterface.cpp
index 8c6ad2e65bd79..5850687e2db7c 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/PadTilingInterface.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/PadTilingInterface.cpp
@@ -50,8 +50,8 @@ getFullRankPaddingSizes(Builder &b, ArrayRef<OpFoldResult> indexingSizes,
// - 1 if we are padding to the next multiple of.
// - indexingSizes[idx] otherwise
if (isZeroInteger(paddingSizes[idx])) {
- paddingSizes[idx] =
- options.padToMultipleOf ? b.getIndexAttr(1) : indexingSizes[idx];
+ paddingSizes[idx] = options.getPadToMultipleOfFlag() ? b.getIndexAttr(1)
+ : indexingSizes[idx];
}
LLVM_DEBUG(DBGS() << "----idx: " << idx << " : " << paddingSizes[idx]
<< "\n");
@@ -149,7 +149,7 @@ linalg::computePaddedShape(OpBuilder &builder, TypedValue<RankedTensorType> v,
// If we are padding to the next multiple of, compose with ceil(sz) * sz.
OpFoldResult paddingDimOfr;
- if (options.padToMultipleOf) {
+ if (options.getPadToMultipleOfFlag()) {
AffineExpr d0, s0;
bindDims(builder.getContext(), d0);
bindSymbols(builder.getContext(), s0);
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
index 57270ec07eaf1..f4a714ce7f1e2 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/Affine/Utils.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "mlir/Analysis/SliceAnalysis.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
@@ -303,7 +304,7 @@ struct VectorizationState {
/// Holds the value sizes of the iteration space to vectorize. Static
/// dimensions are represented by 'arith.constant' and dynamic
/// dimensions by 'tensor/memref.dim'.
- SmallVector<Value> iterSpaceValueSizes;
+ llvm::SmallVectorWithFlags<Value> iterSpaceValueSizes;
/// Holds the canonical vector shape used to vectorize the iteration space.
SmallVector<int64_t> canonicalVecShape;
@@ -326,7 +327,12 @@ struct VectorizationState {
/// dimension, masking can be safely skipped, despite the presence of dynamic
/// shapes. Use this flag with care and only for cases where you are
/// confident the assumption holds.
- bool assumeDynamicDimsMatchVecSizes = false;
+ bool getAssumeDynamicDimsMatchVecSizes() const {
+ return iterSpaceValueSizes.getFlag(0);
+ }
+ void setAssumeDynamicDimsMatchVecSizes(bool Value) {
+ iterSpaceValueSizes.setFlag(0, Value);
+ }
};
LogicalResult
@@ -369,7 +375,7 @@ LogicalResult VectorizationState::initState(RewriterBase &rewriter,
ArrayRef<int64_t> inputVectorSizes,
ArrayRef<bool> inputScalableVecDims,
bool assumeDimsMatchVec) {
- assumeDynamicDimsMatchVecSizes = assumeDimsMatchVec;
+ setAssumeDynamicDimsMatchVecSizes(assumeDimsMatchVec);
// Initialize the insertion point.
rewriter.setInsertionPoint(linalgOp);
@@ -463,7 +469,7 @@ Value VectorizationState::getOrCreateMaskFor(
return Value();
}
- if (assumeDynamicDimsMatchVecSizes) {
+ if (getAssumeDynamicDimsMatchVecSizes()) {
// While for _dynamic_ dim sizes we can _assume_ that the corresponding
// vector sizes match, we still need to check the _static_ dim sizes. Only
// then we can be 100% sure that masking is not required.
@@ -511,7 +517,7 @@ VectorizationState::maskOperation(RewriterBase &rewriter, Operation *opToMask,
if (!mask) {
LDBG() << "No mask required";
- if (assumeDynamicDimsMatchVecSizes) {
+ if (getAssumeDynamicDimsMatchVecSizes()) {
llvm::TypeSwitch<Operation *>(opToMask)
.Case<vector::TransferReadOp, vector::TransferWriteOp>(
[&](auto xferOp) {
diff --git a/mlir/lib/Dialect/NVGPU/TransformOps/NVGPUTransformOps.cpp b/mlir/lib/Dialect/NVGPU/TransformOps/NVGPUTransformOps.cpp
index 153c95c02dc4f..6a70db405ffae 100644
--- a/mlir/lib/Dialect/NVGPU/TransformOps/NVGPUTransformOps.cpp
+++ b/mlir/lib/Dialect/NVGPU/TransformOps/NVGPUTransformOps.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/NVGPU/TransformOps/NVGPUTransformOps.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "mlir/Analysis/SliceAnalysis.h"
#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
@@ -441,8 +442,15 @@ struct MmaSyncBuilder {
std::tuple<IndexCalculator, IndexCalculator, IndexCalculator> indexFns;
std::tuple<SmallVector<int64_t>, SmallVector<int64_t>, SmallVector<int64_t>>
vectorShapes;
- SmallVector<int64_t> mmaShape;
- bool tf32Enabled;
+ llvm::SmallVectorWithFlags<int64_t> mmaShape;
+ bool getTf32Enabled() const { return mmaShape.getFlag(0); }
+ void setTf32Enabled(bool Value) { mmaShape.setFlag(0, Value); }
+
+ MmaSyncInfo(decltype(indexFns) indexFns,
+ decltype(vectorShapes) vectorShapes,
+ SmallVector<int64_t> mmaShape, bool tf32Enabled)
+ : indexFns(std::move(indexFns)), vectorShapes(std::move(vectorShapes)),
+ mmaShape(unsigned(tf32Enabled), std::move(mmaShape)) {}
};
/// Return the specific index calculator for the given `linalgOp` or failure
@@ -789,8 +797,8 @@ FailureOr<Operation *> MmaSyncBuilder::buildMmaSync(LinalgOp linalgOp) {
rhsIndexFn, rhsShape);
Value res = buildMmaSyncMemRefLoadOperand(b, loc, laneId, resMemRef,
resIndexFn, resShape);
- res =
- MmaSyncOp::create(b, loc, lhs, rhs, res, info.mmaShape, info.tf32Enabled);
+ res = MmaSyncOp::create(b, loc, lhs, rhs, res, info.mmaShape,
+ info.getTf32Enabled());
buildMmaSyncMemRefStoreOperand(b, loc, res, laneId, resMemRef, resIndexFn,
resShape);
return res.getDefiningOp();
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCCGToGPU.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCCGToGPU.cpp
index f8560857bb47b..774103ac48933 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCCGToGPU.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCCGToGPU.cpp
@@ -88,6 +88,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/OpenACC/Transforms/Passes.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Arith/Utils/Utils.h"
@@ -468,8 +469,15 @@ class ACCCGToGPULowering {
gpu::LaunchOp getLaunch() const { return launch; }
- bool hasFailed = false;
- bool insideAccumulateGridStride = false;
+ bool getHasFailed() const { return deferredBarrierSeqLoops.getFlag(0); }
+ void setHasFailed(bool Value) { deferredBarrierSeqLoops.setFlag(0, Value); }
+ bool getInsideAccumulateGridStride() const {
+ return deferredBarrierSeqLoops.getFlag(1);
+ }
+ bool setInsideAccumulateGridStride(bool Value) {
+ deferredBarrierSeqLoops.setFlag(1, Value);
+ return Value;
+ }
Value reductionSharedBuf;
// Reduction-accumulator slot (memref) -> the block-reduced value stored into
// it; lets a block combine use the register instead of reloading.
@@ -703,19 +711,45 @@ class ACCCGToGPULowering {
const ACCCGToGPUOptions &options;
gpu::LaunchOp launch;
IRMapping mapping;
- llvm::SmallVector<scf::ParallelOp> loopReductions;
+ llvm::SmallVectorWithFlags<
+ scf::ParallelOp,
+ llvm::CalculateSmallVectorDefaultInlinedElements<scf::ParallelOp>::value,
+ 3>
+ loopReductions;
llvm::DenseMap<gpu::Processor, Value> threadIdMap;
llvm::DenseMap<gpu::Processor, Value> dimensionMap;
// True if ThreadY reduction exists, which triggers subgroup alignment
- bool hasThreadYReduction = false;
+ bool getHasThreadYReduction() const {
+ return deferredBarrierSeqLoops.getFlag(2);
+ }
+ void setHasThreadYReduction(bool Value) {
+ deferredBarrierSeqLoops.setFlag(2, Value);
+ }
// True if a ThreadX reduction exists, whose shuffles stay inside a row
- bool hasThreadXReduction = false;
+ bool getHasThreadXReduction() const {
+ return deferredBarrierSeqLoops.getFlag(3);
+ }
+ void setHasThreadXReduction(bool Value) {
+ deferredBarrierSeqLoops.setFlag(3, Value);
+ }
// True if an array reduction spans any thread dimension
- bool hasThreadLevelArrayReduction = false;
+ bool getHasThreadLevelArrayReduction() const {
+ return loopReductions.getFlag(0);
+ }
+ bool setHasThreadLevelArrayReduction(bool Value) {
+ loopReductions.setFlag(0, Value);
+ return Value;
+ }
// True if any ThreadX routine call exists in the kernel
- bool hasThreadLevelRoutineCall = false;
+ bool getHasThreadLevelRoutineCall() const {
+ return loopReductions.getFlag(1);
+ }
+ void setHasThreadLevelRoutineCall(bool Value) {
+ loopReductions.setFlag(1, Value);
+ }
// True when a per-row ThreadY barrier is emitted
- bool hasThreadYBarrier = false;
+ bool getHasThreadYBarrier() const { return loopReductions.getFlag(2); }
+ void setHasThreadYBarrier(bool Value) { loopReductions.setFlag(2, Value); }
// Reusable privatize broadcast slots per type; disabled for kernels.
llvm::DenseMap<Type, Value> privatizeBroadcastCache;
@@ -737,8 +771,8 @@ class ACCCGToGPULowering {
/// a row may sit anywhere in a subgroup. Array accumulates use atomics
/// instead and still need alignment.
bool isWorkerOnlyShuffleLaunch() const {
- return hasThreadYReduction && !hasThreadXReduction &&
- !hasThreadLevelArrayReduction && staticBlockDimZ == 1 &&
+ return getHasThreadYReduction() && !getHasThreadXReduction() &&
+ !getHasThreadLevelArrayReduction() && staticBlockDimZ == 1 &&
staticBlockDimY > 1 && staticBlockDimY <= options.subgroupSize &&
options.subgroupSize % staticBlockDimX == 0;
}
@@ -747,7 +781,7 @@ class ACCCGToGPULowering {
SharedMemoryBudget sharedMemBudget;
SmallVector<std::string> sharedMemPrivateVarNames;
SmallVector<std::string> threadPrivateVarNames;
- llvm::SmallVector<Operation *, 4> deferredBarrierSeqLoops;
+ llvm::SmallVectorWithFlags<Operation *, 4, 4> deferredBarrierSeqLoops;
Value getThreadId(Location loc, gpu::Dimension dim) {
return gpu::ThreadIdOp::create(rewriter, loc, rewriter.getIndexType(), dim);
@@ -890,7 +924,7 @@ ACCCGToGPULowering::isEligibleForSharedMemory(acc::PrivateLocalOp privateLocal,
FailureOr<bool> isCandidate = isPrivateLocalSharedMemoryCandidate(
privateLocal, computeRegion, module, defaultPolicy, &accSupport);
if (failed(isCandidate)) {
- hasFailed = true;
+ setHasFailed(true);
return std::nullopt;
}
if (!isCandidate.value())
@@ -943,14 +977,16 @@ LogicalResult ACCCGToGPULowering::rewrite() {
// ThreadX is tracked too, to tell worker-only reductions from row shuffles.
computeRegion->walk([&](acc::ReductionAccumulateOp op) {
for (auto parDim : op.getParDimsAttr().getArray()) {
- hasThreadXReduction |= parDim.isThreadX();
- hasThreadYReduction |= parDim.isThreadY();
+ setHasThreadXReduction(int(getHasThreadXReduction()) |
+ (parDim.isThreadX()));
+ setHasThreadYReduction(int(getHasThreadYReduction()) |
+ (parDim.isThreadY()));
}
});
computeRegion->walk([&](acc::ReductionAccumulateArrayOp op) {
for (auto parDim : op.getParDimsAttr().getArray()) {
if (!parDim.isAnyBlock())
- hasThreadLevelArrayReduction = true;
+ setHasThreadLevelArrayReduction(true);
}
});
@@ -962,7 +998,7 @@ LogicalResult ACCCGToGPULowering::rewrite() {
if (mlir::acc::GPUParallelDimAttr parDim =
getAccRoutineCallParDim(callOp, defaultPolicy)) {
if (parDim.isThreadX() || parDim.isThreadY()) {
- hasThreadLevelRoutineCall = true;
+ setHasThreadLevelRoutineCall(true);
return WalkResult::interrupt();
}
}
@@ -1212,11 +1248,11 @@ LogicalResult ACCCGToGPULowering::rewrite() {
// work, so keep its shape instead.
if (isSingleThreadWorkerLaunch())
skipAlign = true;
- if (needsThreadYAlign && !needsThreadXAlign && !hasThreadYBarrier &&
+ if (needsThreadYAlign && !needsThreadXAlign && !getHasThreadYBarrier() &&
isWorkerOnlyShuffleLaunch())
skipAlign = true;
- if ((isShuffleEnabled || hasThreadYBarrier) && !skipAlign) {
+ if ((isShuffleEnabled || getHasThreadYBarrier()) && !skipAlign) {
rewriter.setInsertionPoint(launch);
Value curBlockDimX = launch.getBlockSizeX();
@@ -1303,7 +1339,7 @@ LogicalResult ACCCGToGPULowering::rewrite() {
}
}
- if (hasFailed)
+ if (getHasFailed())
return failure();
if (!threadPrivateVarNames.empty()) {
@@ -1730,7 +1766,7 @@ ACCCGToGPULowering::computeActiveAndInactiveParDims(Operation *op,
diagnosticOp->getLoc(),
"operations in the same predicate region require incompatible "
"ThreadY predication");
- hasFailed = true;
+ setHasFailed(true);
return {};
}
mlir::acc::insertParDim(ancestorParDims, threadY);
@@ -1815,7 +1851,7 @@ void ACCCGToGPULowering::createPerRowBarrier(Location loc) {
return;
}
- hasThreadYBarrier = true;
+ setHasThreadYBarrier(true);
if (staticBlockDimX <= options.subgroupSize) {
emitGPUBarrierSubgroup(rewriter, loc);
@@ -2340,7 +2376,7 @@ bool ACCCGToGPULowering::needsInLoopReuseBarrier(Operation *loopOp) {
// workgroup thread reaches such a call and the callee synchronizes
// internally, so threads leave it in no particular order and can then be
// running different iterations of this loop at the same time.
- if (!hasThreadLevelRoutineCall)
+ if (!getHasThreadLevelRoutineCall())
return false;
bool callsThreadLevelRoutine = false;
loopOp->walk([&](CallOpInterface callOp) -> WalkResult {
@@ -2408,7 +2444,7 @@ void ACCCGToGPULowering::processPredicateRegion(
SmallVector<mlir::acc::GPUParallelDimAttr>>
parDimsPair = computeActiveAndInactiveParDims(
interOp, &interOp.getRegion().front());
- if (hasFailed)
+ if (getHasFailed())
return;
// If ThreadY reduction exists, subgroup alignment is applied
@@ -2418,7 +2454,7 @@ void ACCCGToGPULowering::processPredicateRegion(
// routine call, all ThreadX threads must reach the call so the routine's
// workgroup-wide barriers (e.g. shared memory alloca sync) converge.
// A single-thread worker launch is left unaligned, so it has no such lanes.
- if (hasThreadYReduction && !isSingleThreadWorkerLaunch()) {
+ if (getHasThreadYReduction() && !isSingleThreadWorkerLaunch()) {
MLIRContext *ctx = computeRegion->getContext();
mlir::acc::GPUParallelDimAttr threadXParDim =
mlir::acc::GPUParallelDimAttr::threadXDim(ctx);
@@ -2435,7 +2471,7 @@ void ACCCGToGPULowering::processPredicateRegion(
// We use the pre-computed hasThreadLevelRoutineCall as an early-out
// optimization.
bool regionHasThreadLevelRoutineCall = false;
- if (hasThreadLevelRoutineCall) {
+ if (getHasThreadLevelRoutineCall()) {
interOp.getRegion().walk([&](CallOpInterface callOp) {
if (mlir::acc::GPUParallelDimAttr parDim =
getAccRoutineCallParDim(callOp, defaultPolicy)) {
@@ -3330,7 +3366,7 @@ void ACCCGToGPULowering::processParallelOp(scf::ParallelOp parallelOp) {
mlir::acc::GPUParallelDimAttr parDim = pDimsAttr.getArray().front();
- bool savedGridStrideFlag = insideAccumulateGridStride;
+ bool savedGridStrideFlag = getInsideAccumulateGridStride();
Value savedReductionBuf = reductionSharedBuf;
if (parDim.isThreadX()) {
bool found = false;
@@ -3350,7 +3386,7 @@ void ACCCGToGPULowering::processParallelOp(scf::ParallelOp parallelOp) {
return WalkResult::advance();
});
if (found)
- insideAccumulateGridStride = true;
+ setInsideAccumulateGridStride(true);
}
// common loop body processing for both par0 and 1+
@@ -3399,7 +3435,7 @@ void ACCCGToGPULowering::processParallelOp(scf::ParallelOp parallelOp) {
}
}
}
- if (insideAccumulateGridStride || hasAccumulateSibling) {
+ if (getInsideAccumulateGridStride() || hasAccumulateSibling) {
for (auto launchArg : computeRegion.getLaunchArgs()) {
if (acc::ParWidthOp pw = launchArg.getDefiningOp<acc::ParWidthOp>()) {
if (pw.getParDim().isThreadX()) {
@@ -3480,8 +3516,8 @@ void ACCCGToGPULowering::processParallelOp(scf::ParallelOp parallelOp) {
});
loopReductions.push_back(parallelOp);
}
- insideAccumulateGridStride = savedGridStrideFlag;
- if (!insideAccumulateGridStride && !savedReductionBuf)
+ setInsideAccumulateGridStride(savedGridStrideFlag);
+ if (!getInsideAccumulateGridStride() && !savedReductionBuf)
reductionSharedBuf = Value();
}
diff --git a/mlir/lib/Dialect/Shard/Interfaces/ShardingInterface.cpp b/mlir/lib/Dialect/Shard/Interfaces/ShardingInterface.cpp
index cbdc274940d1e..d5b72b1c8b77a 100644
--- a/mlir/lib/Dialect/Shard/Interfaces/ShardingInterface.cpp
+++ b/mlir/lib/Dialect/Shard/Interfaces/ShardingInterface.cpp
@@ -354,7 +354,7 @@ shard::detail::defaultGetShardingOption(Operation *op,
// 3. Finalize sharding option
removeTrailingEmptySubArray(shardingOption.shardingArray);
if (!anyShardingInResultsOrOperands)
- shardingOption.empty = true;
+ shardingOption.setEmpty(true);
return shardingOption;
}
@@ -486,7 +486,7 @@ static LogicalResult addShardOp(OpBuilder &b, OpOperand &opOperand,
LogicalResult shard::detail::defaultAddShardingAnnotations(
Operation *op, OpBuilder &b, const ShardingOption &shardingOption) {
- assert(!shardingOption.empty && shardingOption.grid);
+ assert(!shardingOption.getEmpty() && shardingOption.grid);
ShardingInterface shardingOp = llvm::cast<ShardingInterface>(op);
SmallVector<utils::IteratorType> loopTypes =
diff --git a/mlir/lib/Dialect/Shard/Transforms/ShardingPropagation.cpp b/mlir/lib/Dialect/Shard/Transforms/ShardingPropagation.cpp
index a4f343c7c87b1..bce1ecfa448b3 100644
--- a/mlir/lib/Dialect/Shard/Transforms/ShardingPropagation.cpp
+++ b/mlir/lib/Dialect/Shard/Transforms/ShardingPropagation.cpp
@@ -68,8 +68,9 @@ static llvm::raw_ostream &operator<<(llvm::raw_ostream &stream,
[[maybe_unused]] static llvm::raw_ostream &operator<<(llvm::raw_ostream &stream,
const ShardingOption &v) {
- return stream << "{empty = " << v.empty << ", grid" << v.grid
- << ", shardingArray = " << v.shardingArray << "}";
+ stream << "{empty = " << v.getEmpty() << ", grid" << v.grid
+ << ", shardingArray = ";
+ return printRange(stream, v.shardingArray) << "}";
}
template <typename Stream, typename... Ts, size_t... Is>
@@ -222,7 +223,7 @@ static FailureOr<ShardingOption> selectShardingOption(
for (ArrayRef<Sharding> operandShardings : possibleOperandShardingAttrs) {
FailureOr<ShardingOption> shardingOption =
shardingOp.getShardingOption(operandShardings, resultShardings);
- if (failed(shardingOption) || shardingOption->empty) {
+ if (failed(shardingOption) || shardingOption->getEmpty()) {
continue;
}
// These shardings may not be the same as those in operandShardings and
@@ -342,7 +343,7 @@ static LogicalResult visitOp(Operation *op, OpBuilder &builder) {
LLVM_DEBUG(DBGS() << "Selected sharding option: " << *shardingOption << "\n");
// sharding info is empty, return immediately
- if (shardingOption->empty)
+ if (shardingOption->getEmpty())
return success();
if (failed(shardingOp.addShardingAnnotations(builder, *shardingOption))) {
diff --git a/mlir/lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.cpp b/mlir/lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.cpp
index b207dfe0d2be2..e333b196fc9e5 100644
--- a/mlir/lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.cpp
+++ b/mlir/lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.cpp
@@ -79,8 +79,7 @@ bool LvlSpec::isValid(Ranks const &ranks) const {
DimLvlMap::DimLvlMap(unsigned symRank, ArrayRef<DimSpec> dimSpecs,
ArrayRef<LvlSpec> lvlSpecs)
- : symRank(symRank), dimSpecs(dimSpecs), lvlSpecs(lvlSpecs),
- mustPrintLvlVars(false) {
+ : symRank(symRank), dimSpecs(dimSpecs), lvlSpecs(lvlSpecs) {
// First, check integrity of the variable-binding structure.
// NOTE: This establishes the invariant that calls to `VarSet::add`
// below cannot cause OOB errors.
@@ -96,7 +95,7 @@ DimLvlMap::DimLvlMap(unsigned symRank, ArrayRef<DimSpec> dimSpecs,
// This LvlVar can be elided iff it isn't overtly used.
lvlSpec.setElideVar(!isUsed);
// If any LvlVar cannot be elided, then must forward-declare all LvlVars.
- mustPrintLvlVars = mustPrintLvlVars || isUsed;
+ setMustPrintLvlVars(getMustPrintLvlVars() || isUsed);
}
}
diff --git a/mlir/lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.h b/mlir/lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.h
index 266fd7a3c5837..b29fc2a0ea3bb 100644
--- a/mlir/lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.h
+++ b/mlir/lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.h
@@ -10,6 +10,7 @@
#define MLIR_DIALECT_SPARSETENSOR_IR_DETAIL_DIMLVLMAP_H
#include "Var.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "mlir/Dialect/SparseTensor/IR/SparseTensor.h"
#include "llvm/ADT/STLForwardCompat.h"
@@ -267,8 +268,9 @@ class DimLvlMap final {
// All these fields are const-after-ctor.
unsigned symRank;
SmallVector<DimSpec> dimSpecs;
- SmallVector<LvlSpec> lvlSpecs;
- bool mustPrintLvlVars;
+ llvm::SmallVectorWithFlags<LvlSpec> lvlSpecs;
+ bool getMustPrintLvlVars() const { return lvlSpecs.getFlag(0); }
+ void setMustPrintLvlVars(bool Value) { lvlSpecs.setFlag(0, Value); }
};
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/SparseTensor/Utils/Merger.cpp b/mlir/lib/Dialect/SparseTensor/Utils/Merger.cpp
index f388a2e44ebdb..4aaa3ee857055 100644
--- a/mlir/lib/Dialect/SparseTensor/Utils/Merger.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Utils/Merger.cpp
@@ -226,7 +226,6 @@ Merger::Merger(unsigned numInputOutputTensors, unsigned numLoops,
: outTensor(numInputOutputTensors - 1),
syntheticTensor(numInputOutputTensors),
numTensors(numInputOutputTensors + 1), numLoops(numLoops),
- hasSparseOut(false),
lvlTypes(numTensors,
std::vector<LevelType>(numLoops, LevelFormat::Undef)),
loopToLvl(numTensors,
@@ -959,7 +958,7 @@ LatSetId Merger::buildLattices(ExprId e, LoopId i) {
TensorId t = syntheticTensor;
if (kind == TensorExp::Kind::kTensor) {
t = expr.tensor;
- if (hasSparseOut && t == outTensor)
+ if (latSets.getFlag(0) && t == outTensor)
t = syntheticTensor;
}
latSets[s].push_back(addLat(t, i, e));
diff --git a/mlir/lib/Dialect/Tosa/Transforms/TosaInferShapes.cpp b/mlir/lib/Dialect/Tosa/Transforms/TosaInferShapes.cpp
index e8f34201b7d18..be30cfba8248a 100644
--- a/mlir/lib/Dialect/Tosa/Transforms/TosaInferShapes.cpp
+++ b/mlir/lib/Dialect/Tosa/Transforms/TosaInferShapes.cpp
@@ -362,7 +362,7 @@ struct TosaInferShapes
auto inferredKnowledge = ValueKnowledge::getPessimisticValueState();
inferredKnowledge.dtype =
cast<ShapedType>(resultTy).getElementType();
- inferredKnowledge.hasRank = predictedShape.hasRank();
+ inferredKnowledge.setHasRank(predictedShape.hasRank());
if (predictedShape.hasRank()) {
for (auto dim : predictedShape.getDims()) {
inferredKnowledge.sizes.push_back(dim);
diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
index c8f4e81ddf07b..eddfcabc026ff 100644
--- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -307,7 +307,7 @@ ExecutionEngine::create(Operation *m, const ExecutionEngineOptions &options,
auto destroyFn = reinterpret_cast<LibraryDestroyFn>(destroySim);
destroyFns.push_back(destroyFn);
}
- engine->destroyFns = std::move(destroyFns);
+ engine->destroyFns.assign(std::move(destroyFns));
// Callback to create the object layer with symbol resolution to current
// process and dynamically linked libraries.
@@ -451,8 +451,8 @@ Error ExecutionEngine::invokePacked(StringRef name,
}
void ExecutionEngine::initialize() {
- if (isInitialized)
+ if (getIsInitialized())
return;
cantFail(jit->initialize(jit->getMainJITDylib()));
- isInitialized = true;
+ setIsInitialized(true);
}
diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index c5d66c27557c5..206f452a752b2 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -27,6 +27,7 @@
#include "mlir/IR/OperationSupport.h"
#include "mlir/IR/Remarks.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/CommandLine.h"
@@ -146,10 +147,20 @@ class MLIRContextImpl {
/// In most cases, creating operation in unregistered dialect is not desired
/// and indicate a misconfiguration of the compiler. This option enables to
/// detect such use cases
- bool allowUnregisteredDialects = false;
+ bool getAllowUnregisteredDialects() const {
+ return sortedRegisteredOperations.getFlag(0);
+ }
+ void setAllowUnregisteredDialects(bool Value) {
+ sortedRegisteredOperations.setFlag(0, Value);
+ }
/// Enable support for multi-threading within MLIR.
- bool threadingIsEnabled = true;
+ bool getThreadingIsEnabled() const {
+ return !sortedRegisteredOperations.getFlag(1);
+ }
+ void setThreadingIsEnabled(bool Value) {
+ sortedRegisteredOperations.setFlag(1, !Value);
+ }
/// Track if we are currently executing in a threaded execution environment
/// (like the pass-manager): this is only a debugging feature to help reducing
@@ -160,10 +171,20 @@ class MLIRContextImpl {
/// If the operation should be attached to diagnostics printed via the
/// Operation::emit methods.
- bool printOpOnDiagnostic = true;
+ bool getPrintOpOnDiagnostic() const {
+ return !sortedRegisteredOperations.getFlag(2);
+ }
+ void setPrintOpOnDiagnostic(bool Value) {
+ sortedRegisteredOperations.setFlag(2, !Value);
+ }
/// If the current stack trace should be attached when emitting diagnostics.
- bool printStackTraceOnDiagnostic = false;
+ bool getPrintStackTraceOnDiagnostic() const {
+ return sortedRegisteredOperations.getFlag(3);
+ }
+ void setPrintStackTraceOnDiagnostic(bool Value) {
+ sortedRegisteredOperations.setFlag(3, Value);
+ }
//===--------------------------------------------------------------------===//
// Other
@@ -191,7 +212,8 @@ class MLIRContextImpl {
/// This is a sorted container of registered operations for a deterministic
/// and efficient `getRegisteredOperations` implementation.
- SmallVector<RegisteredOperationName, 0> sortedRegisteredOperations;
+ llvm::SmallVectorWithFlags<RegisteredOperationName, 0, 4>
+ sortedRegisteredOperations;
/// This is a list of dialects that are created referring to this context.
/// The MLIRContext owns the objects. These need to be declared after the
@@ -282,7 +304,9 @@ class MLIRContextImpl {
public:
MLIRContextImpl(bool threadingIsEnabled)
- : threadingIsEnabled(threadingIsEnabled) {
+ : sortedRegisteredOperations(
+ decltype(this->sortedRegisteredOperations)::withFlags(
+ (unsigned(!(threadingIsEnabled)) << 1))) {
if (threadingIsEnabled) {
ownedThreadPool = std::make_unique<llvm::DefaultThreadPool>();
threadPool = ownedThreadPool.get();
@@ -597,19 +621,21 @@ llvm::hash_code MLIRContext::getRegistryHash() {
}
bool MLIRContext::allowsUnregisteredDialects() {
- return impl->allowUnregisteredDialects;
+ return impl->getAllowUnregisteredDialects();
}
void MLIRContext::allowUnregisteredDialects(bool allowing) {
assert(impl->multiThreadedExecutionContext == 0 &&
"changing MLIRContext `allow-unregistered-dialects` configuration "
"while in a multi-threaded execution context");
- impl->allowUnregisteredDialects = allowing;
+ impl->setAllowUnregisteredDialects(allowing);
}
/// Return true if multi-threading is enabled by the context.
#if LLVM_ENABLE_THREADS
-bool MLIRContext::isMultithreadingEnabled() { return impl->threadingIsEnabled; }
+bool MLIRContext::isMultithreadingEnabled() {
+ return impl->getThreadingIsEnabled();
+}
#endif
/// Set the flag specifying if multi-threading is disabled by the context.
@@ -622,7 +648,7 @@ void MLIRContext::disableMultithreading(bool disable) {
"changing MLIRContext `disable-threading` configuration while "
"in a multi-threaded execution context");
- impl->threadingIsEnabled = !disable;
+ impl->setThreadingIsEnabled(!disable);
// Update the threading mode for each of the uniquers.
impl->affineUniquer.disableMultithreading(disable);
@@ -779,7 +805,7 @@ bool MLIRContext::isInTransientScope() const {
/// Return true if we should attach the operation to diagnostics emitted via
/// Operation::emit.
bool MLIRContext::shouldPrintOpOnDiagnostic() {
- return impl->printOpOnDiagnostic;
+ return impl->getPrintOpOnDiagnostic();
}
/// Set the flag specifying if we should attach the operation to diagnostics
@@ -788,13 +814,13 @@ void MLIRContext::printOpOnDiagnostic(bool enable) {
assert(impl->multiThreadedExecutionContext == 0 &&
"changing MLIRContext `print-op-on-diagnostic` configuration while in "
"a multi-threaded execution context");
- impl->printOpOnDiagnostic = enable;
+ impl->setPrintOpOnDiagnostic(enable);
}
/// Return true if we should attach the current stacktrace to diagnostics when
/// emitted.
bool MLIRContext::shouldPrintStackTraceOnDiagnostic() {
- return impl->printStackTraceOnDiagnostic;
+ return impl->getPrintStackTraceOnDiagnostic();
}
/// Set the flag specifying if we should attach the current stacktrace when
@@ -803,7 +829,7 @@ void MLIRContext::printStackTraceOnDiagnostic(bool enable) {
assert(impl->multiThreadedExecutionContext == 0 &&
"changing MLIRContext `print-stacktrace-on-diagnostic` configuration "
"while in a multi-threaded execution context");
- impl->printStackTraceOnDiagnostic = enable;
+ impl->setPrintStackTraceOnDiagnostic(enable);
}
/// Return information about all registered operations.
diff --git a/mlir/lib/Interfaces/InferTypeOpInterface.cpp b/mlir/lib/Interfaces/InferTypeOpInterface.cpp
index c31e0ae7470e2..dd765e558c409 100644
--- a/mlir/lib/Interfaces/InferTypeOpInterface.cpp
+++ b/mlir/lib/Interfaces/InferTypeOpInterface.cpp
@@ -94,7 +94,8 @@ Type ShapeAdaptor::getElementType() const {
return cast<ShapedTypeComponents *>(val)->getElementType();
}
-void ShapeAdaptor::getDims(SmallVectorImpl<int64_t> &res) const {
+template <typename ShapeStorageT>
+void ShapeAdaptor::getDimsImpl(ShapeStorageT &res) const {
assert(hasRank());
if (auto t = llvm::dyn_cast_if_present<Type>(val)) {
ArrayRef<int64_t> vals = cast<ShapedType>(t).getShape();
@@ -111,10 +112,14 @@ void ShapeAdaptor::getDims(SmallVectorImpl<int64_t> &res) const {
}
}
+void ShapeAdaptor::getDims(SmallVectorImpl<int64_t> &res) const {
+ getDimsImpl(res);
+}
+
void ShapeAdaptor::getDims(ShapedTypeComponents &res) const {
assert(hasRank());
- res.ranked = true;
- getDims(res.dims);
+ getDimsImpl(res.dims);
+ res.dims.setFlag(0, true);
}
int64_t ShapeAdaptor::getDimSize(int index) const {
diff --git a/mlir/lib/TableGen/Class.cpp b/mlir/lib/TableGen/Class.cpp
index 81f1aee73a7f0..79e1634cb974c 100644
--- a/mlir/lib/TableGen/Class.cpp
+++ b/mlir/lib/TableGen/Class.cpp
@@ -339,7 +339,7 @@ void Class::writeDeclTo(raw_indented_ostream &os) const {
}
// Declare the class.
- os << (isStruct ? "struct" : "class") << ' ' << className << ' ';
+ os << (isStructDeclaration() ? "struct" : "class") << ' ' << className << ' ';
// Declare the parent classes, if any.
if (!parents.empty()) {
@@ -401,7 +401,8 @@ Visibility Class::getLastVisibilityDecl() const {
auto reverseDecls = llvm::reverse(declarations);
auto it = llvm::find_if(reverseDecls, llvm::IsaPred<VisibilityDeclaration>);
return it == reverseDecls.end()
- ? (isStruct ? Visibility::Public : Visibility::Private)
+ ? (isStructDeclaration() ? Visibility::Public
+ : Visibility::Private)
: cast<VisibilityDeclaration>(**it).getVisibility();
}
diff --git a/mlir/lib/TableGen/Operator.cpp b/mlir/lib/TableGen/Operator.cpp
index 767f00db2fe81..b189b604894a8 100644
--- a/mlir/lib/TableGen/Operator.cpp
+++ b/mlir/lib/TableGen/Operator.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/Debug.h"
@@ -400,7 +401,7 @@ void Operator::populateTypeInferenceInfo(
// to determine if the result types an be inferred.
auto &recordKeeper = def.getRecords();
auto *inferTrait = recordKeeper.getDef(inferTypeOpInterface);
- allResultsHaveKnownTypes = false;
+ builders.setFlag(0, false);
if (!inferTrait)
return;
@@ -430,7 +431,7 @@ void Operator::populateTypeInferenceInfo(
for (int i = 0; i < getNumResults(); ++i)
resultTypeMapping.emplace_back(operandIdx, "$_self");
- allResultsHaveKnownTypes = true;
+ builders.setFlag(0, true);
traits.push_back(Trait::create(inferTrait->getDefInit()));
return;
}
@@ -442,9 +443,10 @@ void Operator::populateTypeInferenceInfo(
/// is known to have a fully-inferred type, `inferred` is set to true.
struct ResultTypeInference {
/// The list of incoming type inference edges.
- SmallVector<InferredResultType> sources;
+ llvm::SmallVectorWithFlags<InferredResultType> sources;
/// This flag is set to true when the result type is known to be inferrable.
- bool inferred = false;
+ bool getInferred() const { return sources.getFlag(0); }
+ void setInferred(bool Value) { sources.setFlag(0, Value); }
};
// This vector represents the type inference graph, with one node for each
@@ -457,7 +459,7 @@ void Operator::populateTypeInferenceInfo(
if (getResult(idx).constraint.getBuilderCall()) {
infer.sources.emplace_back(InferredResultType::mapResultIndex(idx),
"$_self");
- infer.inferred = true;
+ infer.setInferred(true);
}
}
@@ -487,16 +489,17 @@ void Operator::populateTypeInferenceInfo(
int resultIndex = InferredResultType::unmapResultIndex(target);
ResultTypeInference &infer = inference[resultIndex];
// If the type of the result has already been inferred, do nothing.
- if (infer.inferred)
+ if (infer.getInferred())
continue;
int sourceIndex =
argumentsAndResultsIndex.lookup(def.getValueAsString("lhs"));
infer.sources.emplace_back(sourceIndex,
def.getValueAsString("transformer").str());
// Locally propagate inferredness.
- infer.inferred =
+ infer.setInferred(
InferredResultType::isArgIndex(sourceIndex) ||
- inference[InferredResultType::unmapResultIndex(sourceIndex)].inferred;
+ inference[InferredResultType::unmapResultIndex(sourceIndex)]
+ .getInferred());
continue;
}
@@ -515,13 +518,13 @@ void Operator::populateTypeInferenceInfo(
InferredResultType::isArgIndex(shapedIndex)) {
int resultIndex = InferredResultType::unmapResultIndex(elementsIndex);
ResultTypeInference &infer = inference[resultIndex];
- if (!infer.inferred) {
+ if (!infer.getInferred()) {
infer.sources.emplace_back(
shapedIndex,
"::llvm::SmallVector<::mlir::Type>(::llvm::cast<::mlir::"
"ShapedType>($_self).getNumElements(), "
"::llvm::cast<::mlir::ShapedType>($_self).getElementType())");
- infer.inferred = true;
+ infer.setInferred(true);
}
}
@@ -547,7 +550,7 @@ void Operator::populateTypeInferenceInfo(
if (InferredResultType::isResultIndex(index))
resultIndices.push_back(InferredResultType::unmapResultIndex(index));
if (InferredResultType::isArgIndex(index) ||
- inference[InferredResultType::unmapResultIndex(index)].inferred)
+ inference[InferredResultType::unmapResultIndex(index)].getInferred())
fullyInferredIndex = index;
}
if (fullyInferredIndex) {
@@ -555,9 +558,9 @@ void Operator::populateTypeInferenceInfo(
// aren't already inferred -- a 1 -> N fanout.
for (int resultIndex : resultIndices) {
ResultTypeInference &infer = inference[resultIndex];
- if (!infer.inferred) {
+ if (!infer.getInferred()) {
infer.sources.assign(1, {*fullyInferredIndex, "$_self"});
- infer.inferred = true;
+ infer.setInferred(true);
}
}
} else {
@@ -576,7 +579,7 @@ void Operator::populateTypeInferenceInfo(
// Propagate inferredness until a fixed point.
std::vector<ResultTypeInference *> worklist;
for (ResultTypeInference &infer : inference)
- if (!infer.inferred)
+ if (!infer.getInferred())
worklist.push_back(&infer);
bool changed;
do {
@@ -589,7 +592,7 @@ void Operator::populateTypeInferenceInfo(
assert(InferredResultType::isResultIndex(source.getIndex()));
return inference[InferredResultType::unmapResultIndex(
source.getIndex())]
- .inferred;
+ .getInferred();
});
if (iter == infer.sources.end()) {
++cur;
@@ -597,17 +600,17 @@ void Operator::populateTypeInferenceInfo(
}
changed = true;
- infer.inferred = true;
+ infer.setInferred(true);
// Make this the only source for the result. This breaks any cycles.
infer.sources.assign(1, *iter);
cur = worklist.erase(cur);
}
} while (changed);
- allResultsHaveKnownTypes = worklist.empty();
+ builders.setFlag(0, worklist.empty());
// If the types could be computed, then add type inference trait.
- if (allResultsHaveKnownTypes) {
+ if (allResultTypesKnown()) {
traits.push_back(Trait::create(inferTrait->getDefInit()));
for (const ResultTypeInference &infer : inference)
resultTypeMapping.push_back(infer.sources.front());
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index bb928c4f10ce2..cdc7d50fd3bf8 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -20,6 +20,7 @@
#include "mlir/Support/LLVM.h"
#include "mlir/Target/Cpp/CppEmitter.h"
#include "llvm/ADT/ScopedHashTable.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/Casting.h"
@@ -252,7 +253,7 @@ struct CppEmitter {
/// Returns if all variables for op results and basic block arguments need to
/// be declared at the beginning of a function.
- bool shouldDeclareVariablesAtTop() { return declareVariablesAtTop; };
+ bool shouldDeclareVariablesAtTop() { return getDeclareVariablesAtTop(); };
/// Returns whether this file op should be emitted
bool shouldEmitFile(FileOp file) {
@@ -294,7 +295,12 @@ struct CppEmitter {
/// Boolean to enforce that all variables for op results and block
/// arguments are declared at the beginning of the function. This also
/// includes results from ops located in nested regions.
- bool declareVariablesAtTop;
+ bool getDeclareVariablesAtTop() const {
+ return emittedExpressionPrecedence.getFlag(0);
+ }
+ void setDeclareVariablesAtTop(bool Value) {
+ emittedExpressionPrecedence.setFlag(0, Value);
+ }
/// Only emit file ops whos id matches this value.
std::string fileId;
@@ -319,7 +325,7 @@ struct CppEmitter {
unsigned int valueCount{0};
/// State of the current expression being emitted.
- SmallVector<int> emittedExpressionPrecedence;
+ llvm::SmallVectorWithFlags<int> emittedExpressionPrecedence;
void pushExpressionPrecedence(int precedence) {
emittedExpressionPrecedence.push_back(precedence);
@@ -1568,9 +1574,11 @@ static LogicalResult printOperation(CppEmitter &emitter,
CppEmitter::CppEmitter(raw_ostream &os, bool declareVariablesAtTop,
StringRef fileId)
- : os(os), declareVariablesAtTop(declareVariablesAtTop),
- fileId(fileId.str()), defaultValueMapperScope(valueMapper),
- defaultBlockMapperScope(blockMapper) {
+ : os(os), fileId(fileId.str()), defaultValueMapperScope(valueMapper),
+ defaultBlockMapperScope(blockMapper),
+ emittedExpressionPrecedence(
+ decltype(this->emittedExpressionPrecedence)::withFlags(
+ unsigned(declareVariablesAtTop))) {
labelInScopeCount.push(0);
}
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 07b9d683d309d..6e6cf3a2a0f7f 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "AttrKindDetail.h"
#include "DebugTranslation.h"
@@ -92,7 +93,7 @@ class InstructionCapturingInserter : public llvm::IRBuilderCallbackInserter {
/// Constructs the inserter.
InstructionCapturingInserter()
: llvm::IRBuilderCallbackInserter([this](llvm::Instruction *instruction) {
- if (LLVM_LIKELY(enabled))
+ if (LLVM_LIKELY(getEnabledFlag()))
capturedInstructions.push_back(instruction);
}) {}
@@ -124,21 +125,28 @@ class InstructionCapturingInserter : public llvm::IRBuilderCallbackInserter {
InstructionCapturingInserter *inserter = nullptr;
/// List of instructions in the inserter prior to this scope.
- SmallVector<llvm::Instruction *> previouslyCollectedInstructions;
+ llvm::SmallVectorWithFlags<llvm::Instruction *>
+ previouslyCollectedInstructions;
/// Whether the inserter was enabled prior to this scope.
- bool wasEnabled;
+ bool getWasEnabled() const {
+ return previouslyCollectedInstructions.getFlag(0);
+ }
+ void setWasEnabled(bool Value) {
+ previouslyCollectedInstructions.setFlag(0, Value);
+ }
};
/// Enable or disable the capturing mechanism.
- void setEnabled(bool enabled = true) { this->enabled = enabled; }
+ void setEnabled(bool enabled = true) { this->setEnabledFlag(enabled); }
private:
/// List of captured instructions.
- SmallVector<llvm::Instruction *> capturedInstructions;
+ llvm::SmallVectorWithFlags<llvm::Instruction *> capturedInstructions;
/// Whether the collection is enabled.
- bool enabled = false;
+ bool getEnabledFlag() const { return capturedInstructions.getFlag(0); }
+ void setEnabledFlag(bool Value) { capturedInstructions.setFlag(0, Value); }
};
using CapturingIRBuilder =
@@ -153,8 +161,8 @@ InstructionCapturingInserter::CollectionScope::CollectionScope(
auto &capturingIRBuilder = static_cast<CapturingIRBuilder &>(irBuilder);
inserter = &capturingIRBuilder.getInserter();
- wasEnabled = inserter->enabled;
- if (wasEnabled)
+ setWasEnabled(inserter->getEnabledFlag());
+ if (getWasEnabled())
previouslyCollectedInstructions.swap(inserter->capturedInstructions);
inserter->setEnabled(true);
}
@@ -163,14 +171,17 @@ InstructionCapturingInserter::CollectionScope::~CollectionScope() {
if (!inserter)
return;
+ const bool savedWasEnabled = getWasEnabled();
+ // Preserve this scope's saved state when swapping the flagged vectors.
previouslyCollectedInstructions.swap(inserter->capturedInstructions);
+ setWasEnabled(savedWasEnabled);
// If collection was enabled (likely in another, surrounding scope), keep
// the instructions collected in this scope.
- if (wasEnabled) {
+ if (getWasEnabled()) {
llvm::append_range(inserter->capturedInstructions,
previouslyCollectedInstructions);
}
- inserter->setEnabled(wasEnabled);
+ inserter->setEnabled(getWasEnabled());
}
/// Translates the given data layout spec attribute to the LLVM IR data layout.
diff --git a/mlir/lib/Tools/PDLL/ODS/Operation.cpp b/mlir/lib/Tools/PDLL/ODS/Operation.cpp
index b836ece5071bb..97f69772e6738 100644
--- a/mlir/lib/Tools/PDLL/ODS/Operation.cpp
+++ b/mlir/lib/Tools/PDLL/ODS/Operation.cpp
@@ -20,5 +20,6 @@ Operation::Operation(StringRef name, StringRef summary, StringRef desc,
llvm::SMLoc loc)
: name(name.str()), summary(summary.str()), description(desc.str()),
nativeClassName(nativeClassName.str()),
- supportsTypeInferrence(supportsTypeInferrence),
- location(loc, llvm::SMLoc::getFromPointer(loc.getPointer() + 1)) {}
+ location(loc, llvm::SMLoc::getFromPointer(loc.getPointer() + 1)),
+ attributes(decltype(this->attributes)::withFlags(
+ unsigned(supportsTypeInferrence))) {}
diff --git a/mlir/test/lib/Dialect/Bufferization/TestOneShotModuleBufferize.cpp b/mlir/test/lib/Dialect/Bufferization/TestOneShotModuleBufferize.cpp
index 036e05bfc2e02..78a30272528bf 100644
--- a/mlir/test/lib/Dialect/Bufferization/TestOneShotModuleBufferize.cpp
+++ b/mlir/test/lib/Dialect/Bufferization/TestOneShotModuleBufferize.cpp
@@ -133,7 +133,7 @@ struct TestOneShotModuleBufferizePass
};
// Function signature update only works with memref.cast. Disable it to
// align behaviour for upstream and user casts.
- opt.inferFunctionResultLayout = false;
+ opt.setInferFunctionResultLayout(false);
bufferization::BufferizationState bufferizationState;
diff --git a/mlir/unittests/Dialect/CMakeLists.txt b/mlir/unittests/Dialect/CMakeLists.txt
index 5fd835189ccc7..87f10951552f0 100644
--- a/mlir/unittests/Dialect/CMakeLists.txt
+++ b/mlir/unittests/Dialect/CMakeLists.txt
@@ -18,5 +18,6 @@ add_subdirectory(SCF)
add_subdirectory(SparseTensor)
add_subdirectory(SPIRV)
add_subdirectory(SMT)
+add_subdirectory(Tosa)
add_subdirectory(Transform)
add_subdirectory(Utils)
diff --git a/mlir/unittests/Dialect/Tosa/CMakeLists.txt b/mlir/unittests/Dialect/Tosa/CMakeLists.txt
new file mode 100644
index 0000000000000..ae21954cb3f27
--- /dev/null
+++ b/mlir/unittests/Dialect/Tosa/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_mlir_unittest(MLIRTosaTests
+ ShapeUtilsTest.cpp
+)
+
+mlir_target_link_libraries(MLIRTosaTests
+ PRIVATE
+ MLIRIR
+ MLIRInferTypeOpInterface
+)
diff --git a/mlir/unittests/Dialect/Tosa/ShapeUtilsTest.cpp b/mlir/unittests/Dialect/Tosa/ShapeUtilsTest.cpp
new file mode 100644
index 0000000000000..b4f20cc52e0e3
--- /dev/null
+++ b/mlir/unittests/Dialect/Tosa/ShapeUtilsTest.cpp
@@ -0,0 +1,46 @@
+//===- ShapeUtilsTest.cpp - Tosa shape knowledge tests ------------===//
+//
+// Part of the LLVM Project, under the Apache 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 "mlir/Dialect/Tosa/Utils/ShapeUtils.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::tosa;
+
+TEST(ValueKnowledgeTest, EqualityIgnoresErrors) {
+ SmallVector<int64_t> dimensions(16, 7);
+ ValueKnowledge valid(true, dimensions, {});
+ ValueKnowledge invalid = valid;
+ invalid.setHasError(true);
+ EXPECT_TRUE(valid);
+ EXPECT_FALSE(invalid);
+ EXPECT_EQ(valid, invalid);
+ EXPECT_NE(valid.sizes.getFlags(), invalid.sizes.getFlags());
+}
+
+TEST(ValueKnowledgeTest, JoinAndMeetPreserveRankAndErrors) {
+ SmallVector<int64_t> dimensions(16, 7);
+ ValueKnowledge ranked(true, dimensions, {});
+ ValueKnowledge unranked = ValueKnowledge::getPessimisticValueState();
+ for (ValueKnowledge result : {ValueKnowledge::join(ranked, unranked),
+ ValueKnowledge::join(unranked, ranked),
+ ValueKnowledge::meet(ranked, ranked)}) {
+ EXPECT_TRUE(result);
+ EXPECT_TRUE(result.hasRank());
+ EXPECT_EQ(ArrayRef<int64_t>(result.sizes), ArrayRef<int64_t>(dimensions));
+ }
+ ValueKnowledge result = ValueKnowledge::meet(ranked, unranked);
+ EXPECT_TRUE(result);
+ EXPECT_FALSE(result.hasRank());
+
+ ValueKnowledge conflicting(true, {8}, {});
+ ValueKnowledge singleDimension(true, {7}, {});
+ result = ValueKnowledge::join(singleDimension, conflicting);
+ EXPECT_FALSE(result);
+ EXPECT_TRUE(result.hasRank());
+}
diff --git a/mlir/unittests/Interfaces/InferTypeOpInterfaceTest.cpp b/mlir/unittests/Interfaces/InferTypeOpInterfaceTest.cpp
index 5b4722478dded..9ab931a19c158 100644
--- a/mlir/unittests/Interfaces/InferTypeOpInterfaceTest.cpp
+++ b/mlir/unittests/Interfaces/InferTypeOpInterfaceTest.cpp
@@ -22,6 +22,38 @@
using namespace mlir;
+TEST(ShapedTypeComponentsTest, RankedScalarAndUnrankedCopies) {
+ ShapedTypeComponents unranked;
+ ShapedTypeComponents scalar(ArrayRef<int64_t>{});
+ EXPECT_FALSE(unranked.hasRank());
+ EXPECT_TRUE(scalar.hasRank());
+ EXPECT_TRUE(scalar.getDims().empty());
+
+ unranked = scalar;
+ EXPECT_TRUE(unranked.hasRank());
+ unranked = ShapedTypeComponents();
+ EXPECT_FALSE(unranked.hasRank());
+}
+
+TEST(ShapedTypeComponentsTest, HeapBackedMovesAndShapeAdaptor) {
+ SmallVector<int64_t> dimensions(16, 7);
+ SmallVector<int64_t> input = dimensions;
+ int64_t *data = input.data();
+ ShapedTypeComponents shape(std::move(input));
+ EXPECT_EQ(shape.getDims().data(), data);
+ ShapedTypeComponents moved(std::move(shape));
+ EXPECT_TRUE(moved.hasRank());
+ EXPECT_EQ(moved.getDims(), ArrayRef<int64_t>(dimensions));
+
+ ShapedTypeComponents result;
+ ShapeAdaptor(moved).getDims(result);
+ EXPECT_TRUE(result.hasRank());
+ EXPECT_EQ(result.getDims(), ArrayRef<int64_t>(dimensions));
+ SmallVector<int64_t> output;
+ ShapeAdaptor(result).getDims(output);
+ EXPECT_EQ(output, dimensions);
+}
+
class ValueShapeRangeTest : public testing::Test {
protected:
void SetUp() override {
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index 086904f6b99dd..f320c104bb2de 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVectorWithFlags.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -263,7 +264,7 @@ class ScopArrayInfo final {
Value *getBasePtr() const { return BasePtr; }
// Set IsOnHeap to the value in parameter.
- void setIsOnHeap(bool value) { IsOnHeap = value; }
+ void setIsOnHeap(bool value) { setIsOnHeapFlag(value); }
/// For indirect accesses return the origin SAI of the BP, else null.
const ScopArrayInfo *getBasePtrOriginSAI() const { return BasePtrOriginSAI; }
@@ -343,7 +344,7 @@ class ScopArrayInfo final {
///
/// This property is only relevant if the array is allocated by Polly instead
/// of pre-existing. If false, it is allocated using alloca instead malloca.
- bool isOnHeap() const { return IsOnHeap; }
+ bool isOnHeap() const { return getIsOnHeapFlag(); }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
/// Dump a readable representation to stderr.
@@ -404,13 +405,14 @@ class ScopArrayInfo final {
isl::id Id;
/// True if the newly allocated array is on heap.
- bool IsOnHeap = false;
+ bool getIsOnHeapFlag() const { return DimensionSizesPw.getFlag(0); }
+ void setIsOnHeapFlag(bool Value) { DimensionSizesPw.setFlag(0, Value); }
/// The sizes of each dimension as SCEV*.
SmallVector<const SCEV *, 4> DimensionSizes;
/// The sizes of each dimension as isl::pw_aff.
- SmallVector<isl::pw_aff, 4> DimensionSizesPw;
+ llvm::SmallVectorWithFlags<isl::pw_aff, 4> DimensionSizesPw;
/// The type of this scop array info object.
///
@@ -566,7 +568,7 @@ class MemoryAccess final {
Instruction *AccessInstruction = nullptr;
/// Incoming block and value of a PHINode.
- SmallVector<std::pair<BasicBlock *, Value *>, 4> Incoming;
+ llvm::SmallVectorWithFlags<std::pair<BasicBlock *, Value *>, 4> Incoming;
/// The value associated with this memory access.
///
@@ -581,7 +583,8 @@ class MemoryAccess final {
AssertingVH<Value> AccessValue;
/// Are all the subscripts affine expression?
- bool IsAffine = true;
+ bool getIsAffine() const { return !Incoming.getFlag(0); }
+ void setIsAffine(bool Value) { Incoming.setFlag(0, !Value); }
/// Subscript expression for each dimension.
SubscriptsTy Subscripts;
@@ -1079,7 +1082,7 @@ class MemoryAccess final {
#endif
/// Is the memory access affine?
- bool isAffine() const { return IsAffine; }
+ bool isAffine() const { return getIsAffine(); }
};
raw_ostream &operator<<(raw_ostream &OS, MemoryAccess::ReductionType RT);
@@ -1669,13 +1672,18 @@ class Scop final {
AccFuncVector AccessFunctions;
/// Flag to indicate that the scheduler actually optimized the SCoP.
- bool IsOptimized = false;
+ bool getIsOptimized() const { return InvariantEquivClasses.getFlag(0); }
+ void setIsOptimized(bool Value) { InvariantEquivClasses.setFlag(0, Value); }
/// True if the underlying region has a single exiting block.
- bool HasSingleExitEdge;
+ bool getHasSingleExitEdge() const { return InvariantEquivClasses.getFlag(1); }
+ void setHasSingleExitEdge(bool Value) {
+ InvariantEquivClasses.setFlag(1, Value);
+ }
/// Flag to remember if the SCoP contained an error block or not.
- bool HasErrorBlock = false;
+ bool getHasErrorBlock() const { return InvariantEquivClasses.getFlag(2); }
+ void setHasErrorBlock(bool Value) { InvariantEquivClasses.setFlag(2, Value); }
/// Max loop depth.
unsigned MaxLoopDepth = 0;
@@ -1811,11 +1819,17 @@ class Scop final {
isl::schedule Schedule;
/// Is this Scop marked as not to be transformed by an optimization heuristic?
- bool HasDisableHeuristicsHint = false;
+ bool getHasDisableHeuristicsHint() const {
+ return InvariantEquivClasses.getFlag(3);
+ }
+ void setHasDisableHeuristicsHint(bool Value) {
+ InvariantEquivClasses.setFlag(3, Value);
+ }
/// Whether the schedule has been modified after derived from the CFG by
/// ScopBuilder.
- bool ScheduleModified = false;
+ bool getScheduleModified() const { return MinMaxAliasGroups.getFlag(0); }
+ void setScheduleModified(bool Value) { MinMaxAliasGroups.setFlag(0, Value); }
/// The set of minimal/maximal accesses for each alias group.
///
@@ -1830,14 +1844,15 @@ class Scop final {
///
/// During code generation we will create a runtime alias check for each alias
/// group to ensure the SCoP is executed in an alias free environment.
- MinMaxVectorPairVectorTy MinMaxAliasGroups;
+ llvm::SmallVectorWithFlagsFor<MinMaxVectorPairVectorTy, 1> MinMaxAliasGroups;
/// Mapping from invariant loads to the representing invariant load of
/// their equivalence class.
ValueToValueMap InvEquivClassVMap;
/// List of invariant accesses.
- InvariantEquivClassesTy InvariantEquivClasses;
+ llvm::SmallVectorWithFlagsFor<InvariantEquivClassesTy, 4>
+ InvariantEquivClasses;
/// The smallest array index not yet assigned.
long ArrayIdx = 0;
@@ -2130,18 +2145,16 @@ class Scop final {
InvariantEquivClassTy *lookupInvariantEquivClass(Value *Val);
/// Return the set of invariant accesses.
- InvariantEquivClassesTy &getInvariantAccesses() {
- return InvariantEquivClasses;
- }
+ auto &getInvariantAccesses() { return InvariantEquivClasses; }
/// Check if the scop has any invariant access.
bool hasInvariantAccesses() { return !InvariantEquivClasses.empty(); }
/// Mark the SCoP as optimized by the scheduler.
- void markAsOptimized() { IsOptimized = true; }
+ void markAsOptimized() { setIsOptimized(true); }
/// Check if the SCoP has been optimized by the scheduler.
- bool isOptimized() const { return IsOptimized; }
+ bool isOptimized() const { return getIsOptimized(); }
/// Return the ID of the Scop
int getID() const { return ID; }
@@ -2276,9 +2289,7 @@ class Scop final {
bool hasTrivialInvalidContext() const { return InvalidContext.is_empty(); }
/// Return all alias groups for this SCoP.
- const MinMaxVectorPairVectorTy &getAliasGroups() const {
- return MinMaxAliasGroups;
- }
+ const auto &getAliasGroups() const { return MinMaxAliasGroups; }
void addAliasGroup(MinMaxVectorTy &MinMaxAccessesReadWrite,
MinMaxVectorTy &MinMaxAccessesReadOnly) {
@@ -2451,13 +2462,13 @@ class Scop final {
bool isProfitable(bool ScalarsAreUnprofitable) const;
/// Return true if the SCoP contained at least one error block.
- bool hasErrorBlock() const { return HasErrorBlock; }
+ bool hasErrorBlock() const { return getHasErrorBlock(); }
/// Notify SCoP that it contains an error block
- void notifyErrorBlock() { HasErrorBlock = true; }
+ void notifyErrorBlock() { setHasErrorBlock(true); }
/// Return true if the underlying region has a single exiting block.
- bool hasSingleExitEdge() const { return HasSingleExitEdge; }
+ bool hasSingleExitEdge() const { return getHasSingleExitEdge(); }
/// Print the static control part.
///
@@ -2576,7 +2587,7 @@ class Scop final {
/// Whether the schedule is the original schedule as derived from the CFG by
/// ScopBuilder.
- bool isOriginalSchedule() const { return !ScheduleModified; }
+ bool isOriginalSchedule() const { return !getScheduleModified(); }
/// Intersects the domains of all statements in the SCoP.
///
@@ -2672,10 +2683,12 @@ class Scop final {
/// Is this Scop marked as not to be transformed by an optimization heuristic?
/// In this case, only user-directed transformations are allowed.
- bool hasDisableHeuristicsHint() const { return HasDisableHeuristicsHint; }
+ bool hasDisableHeuristicsHint() const {
+ return getHasDisableHeuristicsHint();
+ }
/// Mark this Scop to not apply an optimization heuristic.
- void markDisableHeuristics() { HasDisableHeuristicsHint = true; }
+ void markDisableHeuristics() { setHasDisableHeuristicsHint(true); }
};
/// Print Scop scop to raw_ostream OS.
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 6757f3ba057ea..522d23ab5ae49 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -919,7 +919,8 @@ MemoryAccess::MemoryAccess(ScopStmt *Stmt, Instruction *AccessInst,
: Kind(Kind), AccType(AccType), Statement(Stmt), InvalidDomain(),
BaseAddr(BaseAddress), ElementType(ElementType),
Sizes(Sizes.begin(), Sizes.end()), AccessInstruction(AccessInst),
- AccessValue(AccessValue), IsAffine(Affine),
+ Incoming(decltype(this->Incoming)::withFlags(unsigned(!(Affine)))),
+ AccessValue(AccessValue),
Subscripts(Subscripts.begin(), Subscripts.end()), AccessRelation(),
NewAccessRelation() {
static const std::string TypeStrings[] = {"", "_Read", "_Write", "_MayWrite"};
@@ -1651,8 +1652,10 @@ Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
DominatorTree &DT, ScopDetection::DetectionContext &DC,
OptimizationRemarkEmitter &ORE, int ID)
: IslCtx(isl_ctx_alloc(), isl_ctx_free), SE(&ScalarEvolution), DT(&DT),
- R(R), name(std::nullopt), HasSingleExitEdge(R.getExitingBlock()), DC(DC),
- ORE(ORE), Affinator(this, LI), ID(ID) {
+ R(R), name(std::nullopt), DC(DC), ORE(ORE), Affinator(this, LI),
+ InvariantEquivClasses(decltype(this->InvariantEquivClasses)::withFlags(
+ (unsigned(bool(R.getExitingBlock())) << 1))),
+ ID(ID) {
// Options defaults that are different from ISL's.
isl_options_set_schedule_serialize_sccs(IslCtx.get(), true);
@@ -2361,12 +2364,12 @@ void Scop::setSchedule(isl::union_map NewSchedule) {
auto S = isl::schedule::from_domain(getDomains());
Schedule = S.insert_partial_schedule(
isl::multi_union_pw_aff::from_union_map(NewSchedule));
- ScheduleModified = true;
+ setScheduleModified(true);
}
void Scop::setScheduleTree(isl::schedule NewSchedule) {
Schedule = NewSchedule;
- ScheduleModified = true;
+ setScheduleModified(true);
}
bool Scop::restrictDomains(isl::union_set Domain) {
More information about the llvm-branch-commits
mailing list