[llvm] [CodeExtractor] Format CodeExtractor header, NFC (PR #178662)

Sergio Afonso via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 29 07:10:57 PST 2026


https://github.com/skatrak updated https://github.com/llvm/llvm-project/pull/178662

>From 0162a3e173e6df27cd93a9d2691d331d8765724d Mon Sep 17 00:00:00 2001
From: Sergio Afonso <safonsof at amd.com>
Date: Thu, 29 Jan 2026 13:53:19 +0000
Subject: [PATCH] [CodeExtractor] Format CodeExtractor header, NFC

This patch applies clang-format to the CodeExtractor header and updates
usage of the LLVM_ABI macro to prevent unrelated patches touching this
file from having to make these changes in order to pass pre-merge checks.
---
 .../llvm/Transforms/Utils/CodeExtractor.h     | 470 +++++++++---------
 1 file changed, 230 insertions(+), 240 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Utils/CodeExtractor.h b/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
index 3e2c69b47bc48..e117a33d3435f 100644
--- a/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
+++ b/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -71,250 +71,240 @@ class CodeExtractorAnalysisCache {
                                               AllocaInst *Addr) const;
 };
 
-  /// Utility class for extracting code into a new function.
+/// Utility class for extracting code into a new function.
+///
+/// This utility provides a simple interface for extracting some sequence of
+/// code into its own function, replacing it with a call to that function. It
+/// also provides various methods to query about the nature and result of such a
+/// transformation.
+///
+/// The rough algorithm used is:
+/// 1) Find both the inputs and outputs for the extracted region.
+/// 2) Pass the inputs as arguments, remapping them within the extracted
+///    function to arguments.
+/// 3) Add allocas for any scalar outputs, adding all of the outputs' allocas as
+///    arguments, and inserting stores to the arguments for any scalars.
+class LLVM_ABI CodeExtractor {
+  using ValueSet = SetVector<Value *>;
+
+  // Various bits of state computed on construction.
+  DominatorTree *const DT;
+  const bool AggregateArgs;
+  BlockFrequencyInfo *BFI;
+  BranchProbabilityInfo *BPI;
+  AssumptionCache *AC;
+
+  // A block outside of the extraction set where any intermediate allocations
+  // will be placed inside. If this is null, allocations will be placed in the
+  // entry block of the function.
+  BasicBlock *AllocationBlock;
+
+  // If true, varargs functions can be extracted.
+  bool AllowVarArgs;
+
+  // Bits of intermediate state computed at various phases of extraction.
+  SetVector<BasicBlock *> Blocks;
+
+  /// Lists of blocks that are branched from the code region to be extracted,
+  /// also called the exit blocks. Each block is contained at most once. Its
+  /// order defines the return value of the extracted function.
+  ///
+  /// When there is just one (or no) exit block, the return value is irrelevant.
   ///
-  /// This utility provides a simple interface for extracting some sequence of
-  /// code into its own function, replacing it with a call to that function. It
-  /// also provides various methods to query about the nature and result of
-  /// such a transformation.
+  /// When there are exactly two exit blocks, the extracted function returns a
+  /// boolean. For ExtractedFuncRetVals[0], it returns 'true'. For
+  /// ExtractedFuncRetVals[1] it returns 'false'.
+  /// NOTE: Since a boolean is represented by i1, ExtractedFuncRetVals[0]
+  ///       returns 1 and ExtractedFuncRetVals[1] returns 0, which opposite of
+  ///       the regular pattern below.
+  ///
+  /// 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;
+
+  // Suffix to use when creating extracted function (appended to the original
+  // function name + "."). If empty, the default is to use the entry block
+  // label, if non-empty, otherwise "extracted".
+  std::string Suffix;
+
+  // If true, the outlined function has aggregate argument in zero address
+  // space.
+  bool ArgsInZeroAddressSpace;
+
+public:
+  /// Create a code extractor for a sequence of blocks.
+  ///
+  /// Given a sequence of basic blocks where the first block in the sequence
+  /// dominates the rest, prepare a code extractor object for pulling this
+  /// sequence out into its new function. When a DominatorTree is also given,
+  /// extra checking and transformations are enabled. If AllowVarArgs is true,
+  /// vararg functions can be extracted. This is safe, if all vararg handling
+  /// code is extracted, including vastart. If AllowAlloca is true, then
+  /// extraction of blocks containing alloca instructions would be possible,
+  /// however code extractor won't validate whether extraction is legal. Any new
+  /// allocations will be placed in the AllocationBlock, unless it is null, in
+  /// which case it will be placed in the entry block of the function from which
+  /// the code is being extracted. If ArgsInZeroAddressSpace param is set to
+  /// true, then the aggregate param pointer of the outlined function is
+  /// declared in zero address space.
+  CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = nullptr,
+                bool AggregateArgs = false, BlockFrequencyInfo *BFI = nullptr,
+                BranchProbabilityInfo *BPI = nullptr,
+                AssumptionCache *AC = nullptr, bool AllowVarArgs = false,
+                bool AllowAlloca = false, BasicBlock *AllocationBlock = nullptr,
+                std::string Suffix = "", bool ArgsInZeroAddressSpace = false);
+
+  /// Perform the extraction, returning the new function.
+  ///
+  /// Returns zero when called on a CodeExtractor instance where isEligible
+  /// returns false.
+  Function *extractCodeRegion(const CodeExtractorAnalysisCache &CEAC);
+
+  /// Perform the extraction, returning the new function and providing an
+  /// interface to see what was categorized as inputs and outputs.
   ///
-  /// The rough algorithm used is:
-  /// 1) Find both the inputs and outputs for the extracted region.
-  /// 2) Pass the inputs as arguments, remapping them within the extracted
-  ///    function to arguments.
-  /// 3) Add allocas for any scalar outputs, adding all of the outputs' allocas
-  ///    as arguments, and inserting stores to the arguments for any scalars.
-  class CodeExtractor {
-    using ValueSet = SetVector<Value *>;
-
-    // Various bits of state computed on construction.
-    DominatorTree *const DT;
-    const bool AggregateArgs;
-    BlockFrequencyInfo *BFI;
-    BranchProbabilityInfo *BPI;
-    AssumptionCache *AC;
-
-    // A block outside of the extraction set where any intermediate
-    // allocations will be placed inside. If this is null, allocations
-    // will be placed in the entry block of the function.
-    BasicBlock *AllocationBlock;
-
-    // If true, varargs functions can be extracted.
-    bool AllowVarArgs;
-
-    // Bits of intermediate state computed at various phases of extraction.
-    SetVector<BasicBlock *> Blocks;
-
-    /// Lists of blocks that are branched from the code region to be extracted,
-    /// also called the exit blocks. Each block is contained at most once. Its
-    /// order defines the return value of the extracted function.
-    ///
-    /// When there is just one (or no) exit block, the return value is
-    /// irrelevant.
-    ///
-    /// When there are exactly two exit blocks, the extracted function returns a
-    /// boolean. For ExtractedFuncRetVals[0], it returns 'true'. For
-    /// ExtractedFuncRetVals[1] it returns 'false'.
-    /// NOTE: Since a boolean is represented by i1, ExtractedFuncRetVals[0]
-    ///       returns 1 and ExtractedFuncRetVals[1] returns 0, which opposite
-    ///       of the regular pattern below.
-    ///
-    /// 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;
-
-    // Suffix to use when creating extracted function (appended to the original
-    // function name + "."). If empty, the default is to use the entry block
-    // label, if non-empty, otherwise "extracted".
-    std::string Suffix;
-
-    // If true, the outlined function has aggregate argument in zero address
-    // space.
-    bool ArgsInZeroAddressSpace;
-
-  public:
-    /// Create a code extractor for a sequence of blocks.
-    ///
-    /// Given a sequence of basic blocks where the first block in the sequence
-    /// dominates the rest, prepare a code extractor object for pulling this
-    /// sequence out into its new function. When a DominatorTree is also given,
-    /// extra checking and transformations are enabled. If AllowVarArgs is true,
-    /// vararg functions can be extracted. This is safe, if all vararg handling
-    /// code is extracted, including vastart. If AllowAlloca is true, then
-    /// extraction of blocks containing alloca instructions would be possible,
-    /// however code extractor won't validate whether extraction is legal.
-    /// Any new allocations will be placed in the AllocationBlock, unless
-    /// it is null, in which case it will be placed in the entry block of
-    /// the function from which the code is being extracted.
-    /// If ArgsInZeroAddressSpace param is set to true, then the aggregate
-    /// param pointer of the outlined function is declared in zero address
-    /// space.
-    LLVM_ABI
-    CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = nullptr,
-                  bool AggregateArgs = false, BlockFrequencyInfo *BFI = nullptr,
-                  BranchProbabilityInfo *BPI = nullptr,
-                  AssumptionCache *AC = nullptr, bool AllowVarArgs = false,
-                  bool AllowAlloca = false,
-                  BasicBlock *AllocationBlock = nullptr,
-                  std::string Suffix = "", bool ArgsInZeroAddressSpace = false);
-
-    /// Perform the extraction, returning the new function.
-    ///
-    /// Returns zero when called on a CodeExtractor instance where isEligible
-    /// returns false.
-    LLVM_ABI Function *
-    extractCodeRegion(const CodeExtractorAnalysisCache &CEAC);
-
-    /// Perform the extraction, returning the new function and providing an
-    /// interface to see what was categorized as inputs and outputs.
-    ///
-    /// \param CEAC - Cache to speed up operations for the CodeExtractor when
-    /// hoisting, and extracting lifetime values and assumes.
-    /// \param Inputs [in/out] - filled with  values marked as inputs to the
-    /// newly outlined function.
-    /// \param Outputs [out] - filled with values marked as outputs to the
-    /// newly outlined function.
-    /// \returns zero when called on a CodeExtractor instance where isEligible
-    /// returns false.
-    LLVM_ABI Function *extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
-                                         ValueSet &Inputs, ValueSet &Outputs);
-
-    /// Verify that assumption cache isn't stale after a region is extracted.
-    /// Returns true when verifier finds errors. AssumptionCache is passed as
-    /// parameter to make this function stateless.
-    LLVM_ABI static bool verifyAssumptionCache(const Function &OldFunc,
-                                               const Function &NewFunc,
-                                               AssumptionCache *AC);
-
-    /// Test whether this code extractor is eligible.
-    ///
-    /// Based on the blocks used when constructing the code extractor,
-    /// determine whether it is eligible for extraction.
-    ///
-    /// Checks that varargs handling (with vastart and vaend) is only done in
-    /// the outlined blocks.
-    LLVM_ABI bool isEligible() const;
-
-    /// Compute the set of input values and output values for the code.
-    ///
-    /// These can be used either when performing the extraction or to evaluate
-    /// the expected size of a call to the extracted function. Note that this
-    /// work cannot be cached between the two as once we decide to extract
-    /// a code sequence, that sequence is modified, including changing these
-    /// sets, before extraction occurs. These modifications won't have any
-    /// significant impact on the cost however.
-    LLVM_ABI void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs,
-                                    const ValueSet &Allocas,
-                                    bool CollectGlobalInputs = false) const;
-
-    /// Check if life time marker nodes can be hoisted/sunk into the outline
-    /// region.
-    ///
-    /// Returns true if it is safe to do the code motion.
-    LLVM_ABI bool
-    isLegalToShrinkwrapLifetimeMarkers(const CodeExtractorAnalysisCache &CEAC,
-                                       Instruction *AllocaAddr) const;
-
-    /// Find the set of allocas whose life ranges are contained within the
-    /// outlined region.
-    ///
-    /// Allocas which have life_time markers contained in the outlined region
-    /// should be pushed to the outlined function. The address bitcasts that
-    /// are used by the lifetime markers are also candidates for shrink-
-    /// wrapping. The instructions that need to be sunk are collected in
-    /// 'Allocas'.
-    LLVM_ABI void findAllocas(const CodeExtractorAnalysisCache &CEAC,
-                              ValueSet &SinkCands, ValueSet &HoistCands,
-                              BasicBlock *&ExitBlock) const;
-
-    /// Find or create a block within the outline region for placing hoisted
-    /// code.
-    ///
-    /// CommonExitBlock is block outside the outline region. It is the common
-    /// successor of blocks inside the region. If there exists a single block
-    /// inside the region that is the predecessor of CommonExitBlock, that block
-    /// will be returned. Otherwise CommonExitBlock will be split and the
-    /// original block will be added to the outline region.
-    LLVM_ABI BasicBlock *
-    findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock);
-
-    /// Exclude a value from aggregate argument passing when extracting a code
-    /// region, passing it instead as a scalar.
-    LLVM_ABI void excludeArgFromAggregate(Value *Arg);
-
-  private:
-    struct LifetimeMarkerInfo {
-      bool SinkLifeStart = false;
-      bool HoistLifeEnd = false;
-      Instruction *LifeStart = nullptr;
-      Instruction *LifeEnd = nullptr;
-    };
-
-    ValueSet ExcludeArgsFromAggregate;
-
-    LifetimeMarkerInfo
-    getLifetimeMarkers(const CodeExtractorAnalysisCache &CEAC,
-                       Instruction *Addr, BasicBlock *ExitBlock) const;
-
-    /// Updates the list of SwitchCases (corresponding to exit blocks) after
-    /// changes of the control flow or the Blocks list.
-    void computeExtractedFuncRetVals();
-
-    /// Return the type used for the return code of the extracted function to
-    /// indicate which exit block to jump to.
-    Type *getSwitchType();
-
-    void severSplitPHINodesOfEntry(BasicBlock *&Header);
-    void severSplitPHINodesOfExits();
-    void splitReturnBlocks();
-
-    void moveCodeToFunction(Function *newFunction);
-
-    void calculateNewCallTerminatorWeights(
-        BasicBlock *CodeReplacer,
-        const DenseMap<BasicBlock *, BlockFrequency> &ExitWeights,
-        BranchProbabilityInfo *BPI);
-
-    /// Normalizes the control flow of the extracted regions, such as ensuring
-    /// that the extracted region does not contain a return instruction.
-    void normalizeCFGForExtraction(BasicBlock *&header);
-
-    /// Generates the function declaration for the function containing the
-    /// extracted code.
-    Function *constructFunctionDeclaration(const ValueSet &inputs,
-                                           const ValueSet &outputs,
-                                           BlockFrequency EntryFreq,
-                                           const Twine &Name,
-                                           ValueSet &StructValues,
-                                           StructType *&StructTy);
-
-    /// Generates the code for the extracted function. That is: a prolog, the
-    /// moved or copied code from the original function, and epilogs for each
-    /// exit.
-    void emitFunctionBody(const ValueSet &inputs, const ValueSet &outputs,
-                          const ValueSet &StructValues, Function *newFunction,
-                          StructType *StructArgTy, BasicBlock *header,
-                          const ValueSet &SinkingCands,
-                          SmallVectorImpl<Value *> &NewValues);
-
-    /// Generates a Basic Block that calls the extracted function.
-    CallInst *emitReplacerCall(const ValueSet &inputs, const ValueSet &outputs,
-                               const ValueSet &StructValues,
-                               Function *newFunction, StructType *StructArgTy,
-                               Function *oldFunction, BasicBlock *ReplIP,
-                               BlockFrequency EntryFreq,
-                               ArrayRef<Value *> LifetimesStart,
-                               std::vector<Value *> &Reloads);
-
-    /// Connects the basic block containing the call to the extracted function
-    /// into the original function's control flow.
-    void insertReplacerCall(
-        Function *oldFunction, BasicBlock *header, BasicBlock *codeReplacer,
-        const ValueSet &outputs, ArrayRef<Value *> Reloads,
-        const DenseMap<BasicBlock *, BlockFrequency> &ExitWeights);
+  /// \param CEAC - Cache to speed up operations for the CodeExtractor when
+  /// hoisting, and extracting lifetime values and assumes.
+  /// \param Inputs [in/out] - filled with  values marked as inputs to the newly
+  /// outlined function.
+  /// \param Outputs [out] - filled with values marked as outputs to the newly
+  /// outlined function.
+  /// \returns zero when called on a CodeExtractor instance where isEligible
+  /// returns false.
+  Function *extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
+                              ValueSet &Inputs, ValueSet &Outputs);
+
+  /// Verify that assumption cache isn't stale after a region is extracted.
+  /// Returns true when verifier finds errors. AssumptionCache is passed as
+  /// parameter to make this function stateless.
+  static bool verifyAssumptionCache(const Function &OldFunc,
+                                    const Function &NewFunc,
+                                    AssumptionCache *AC);
+
+  /// Test whether this code extractor is eligible.
+  ///
+  /// Based on the blocks used when constructing the code extractor, determine
+  /// whether it is eligible for extraction.
+  ///
+  /// Checks that varargs handling (with vastart and vaend) is only done in the
+  /// outlined blocks.
+  bool isEligible() const;
+
+  /// Compute the set of input values and output values for the code.
+  ///
+  /// These can be used either when performing the extraction or to evaluate the
+  /// expected size of a call to the extracted function. Note that this work
+  /// cannot be cached between the two as once we decide to extract a code
+  /// sequence, that sequence is modified, including changing these sets, before
+  /// extraction occurs. These modifications won't have any significant impact
+  /// on the cost however.
+  void findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs,
+                         const ValueSet &Allocas,
+                         bool CollectGlobalInputs = false) const;
+
+  /// Check if life time marker nodes can be hoisted/sunk into the outline
+  /// region.
+  ///
+  /// Returns true if it is safe to do the code motion.
+  bool
+  isLegalToShrinkwrapLifetimeMarkers(const CodeExtractorAnalysisCache &CEAC,
+                                     Instruction *AllocaAddr) const;
+
+  /// Find the set of allocas whose life ranges are contained within the
+  /// outlined region.
+  ///
+  /// Allocas which have life_time markers contained in the outlined region
+  /// should be pushed to the outlined function. The address bitcasts that are
+  /// used by the lifetime markers are also candidates for shrink-wrapping. The
+  /// instructions that need to be sunk are collected in 'Allocas'.
+  void findAllocas(const CodeExtractorAnalysisCache &CEAC, ValueSet &SinkCands,
+                   ValueSet &HoistCands, BasicBlock *&ExitBlock) const;
+
+  /// Find or create a block within the outline region for placing hoisted code.
+  ///
+  /// CommonExitBlock is block outside the outline region. It is the common
+  /// successor of blocks inside the region. If there exists a single block
+  /// inside the region that is the predecessor of CommonExitBlock, that block
+  /// will be returned. Otherwise CommonExitBlock will be split and the original
+  /// block will be added to the outline region.
+  BasicBlock *findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock);
+
+  /// Exclude a value from aggregate argument passing when extracting a code
+  /// region, passing it instead as a scalar.
+  void excludeArgFromAggregate(Value *Arg);
+
+private:
+  struct LifetimeMarkerInfo {
+    bool SinkLifeStart = false;
+    bool HoistLifeEnd = false;
+    Instruction *LifeStart = nullptr;
+    Instruction *LifeEnd = nullptr;
   };
 
+  ValueSet ExcludeArgsFromAggregate;
+
+  LifetimeMarkerInfo getLifetimeMarkers(const CodeExtractorAnalysisCache &CEAC,
+                                        Instruction *Addr,
+                                        BasicBlock *ExitBlock) const;
+
+  /// Updates the list of SwitchCases (corresponding to exit blocks) after
+  /// changes of the control flow or the Blocks list.
+  void computeExtractedFuncRetVals();
+
+  /// Return the type used for the return code of the extracted function to
+  /// indicate which exit block to jump to.
+  Type *getSwitchType();
+
+  void severSplitPHINodesOfEntry(BasicBlock *&Header);
+  void severSplitPHINodesOfExits();
+  void splitReturnBlocks();
+
+  void moveCodeToFunction(Function *newFunction);
+
+  void calculateNewCallTerminatorWeights(
+      BasicBlock *CodeReplacer,
+      const DenseMap<BasicBlock *, BlockFrequency> &ExitWeights,
+      BranchProbabilityInfo *BPI);
+
+  /// Normalizes the control flow of the extracted regions, such as ensuring
+  /// that the extracted region does not contain a return instruction.
+  void normalizeCFGForExtraction(BasicBlock *&header);
+
+  /// Generates the function declaration for the function containing the
+  /// extracted code.
+  Function *
+  constructFunctionDeclaration(const ValueSet &inputs, const ValueSet &outputs,
+                               BlockFrequency EntryFreq, const Twine &Name,
+                               ValueSet &StructValues, StructType *&StructTy);
+
+  /// Generates the code for the extracted function. That is: a prolog, the
+  /// moved or copied code from the original function, and epilogs for each
+  /// exit.
+  void emitFunctionBody(const ValueSet &inputs, const ValueSet &outputs,
+                        const ValueSet &StructValues, Function *newFunction,
+                        StructType *StructArgTy, BasicBlock *header,
+                        const ValueSet &SinkingCands,
+                        SmallVectorImpl<Value *> &NewValues);
+
+  /// Generates a Basic Block that calls the extracted function.
+  CallInst *emitReplacerCall(const ValueSet &inputs, const ValueSet &outputs,
+                             const ValueSet &StructValues,
+                             Function *newFunction, StructType *StructArgTy,
+                             Function *oldFunction, BasicBlock *ReplIP,
+                             BlockFrequency EntryFreq,
+                             ArrayRef<Value *> LifetimesStart,
+                             std::vector<Value *> &Reloads);
+
+  /// Connects the basic block containing the call to the extracted function
+  /// into the original function's control flow.
+  void
+  insertReplacerCall(Function *oldFunction, BasicBlock *header,
+                     BasicBlock *codeReplacer, const ValueSet &outputs,
+                     ArrayRef<Value *> Reloads,
+                     const DenseMap<BasicBlock *, BlockFrequency> &ExitWeights);
+};
+
 } // end namespace llvm
 
 #endif // LLVM_TRANSFORMS_UTILS_CODEEXTRACTOR_H



More information about the llvm-commits mailing list