[llvm] [llvm] export private symbols needed by unittests (PR #145767)
Andrew Rogers via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 25 12:05:15 PDT 2025
https://github.com/andrurogerz created https://github.com/llvm/llvm-project/pull/145767
## Purpose
Export a small number of private LLVM symbols so that unit tests can still build/run when LLVM is built as a Windows DLL or a shared library with default hidden symbol visibility.
## Background
The effort to build LLVM as a WIndows DLL is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307).
Some LLVM unit tests use internal/private symbols that are not part of LLVM's public interface. When building LLVM as a DLL or shared library with default hidden symbol visibility, the symbols are not available when the unit test links against the DLL or shared library.
This problem can be solved in one of two ways:
1. Export the private symbols from the DLL.
2. Link the unit tests against the intermediate static libraries instead of the final LLVM DLL.
This PR applies option 1.
>From 33a1da7427436b8afa0fed7aac2f28a8c7deb721 Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Wed, 25 Jun 2025 11:56:45 -0700
Subject: [PATCH 1/4] [llvm] export private API so that CodeGenTests builds
against Windows DLL
---
llvm/lib/CodeGen/AsmPrinter/DIEHash.h | 3 +-
.../LiveDebugValues/InstrRefBasedImpl.h | 29 ++++++++++---------
llvm/lib/CodeGen/MLRegAllocEvictAdvisor.h | 5 ++--
llvm/lib/CodeGen/RegAllocScore.h | 7 +++--
4 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.h b/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
index 24a973b392715..d8c4b393e7f1f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/DIE.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/MD5.h"
namespace llvm {
@@ -38,7 +39,7 @@ class DIEHash {
uint64_t computeCUSignature(StringRef DWOName, const DIE &Die);
/// Computes the type signature.
- uint64_t computeTypeSignature(const DIE &Die);
+ LLVM_ABI uint64_t computeTypeSignature(const DIE &Die);
// Helper routines to process parts of a DIE.
private:
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
index 810a71f4d8af4..ac95093f7d3b2 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/Support/Compiler.h"
#include <optional>
#include "LiveDebugValues.h"
@@ -204,8 +205,8 @@ class ValueIDNum {
.str();
}
- static ValueIDNum EmptyValue;
- static ValueIDNum TombstoneValue;
+ LLVM_ABI static ValueIDNum EmptyValue;
+ LLVM_ABI static ValueIDNum TombstoneValue;
};
} // End namespace LiveDebugValues
@@ -425,7 +426,7 @@ struct DbgOpID {
DbgOpID(uint32_t RawID) : RawID(RawID) {}
DbgOpID(bool IsConst, uint32_t Index) : ID({IsConst, Index}) {}
- static DbgOpID UndefID;
+ LLVM_ABI static DbgOpID UndefID;
bool operator==(const DbgOpID &Other) const { return RawID == Other.RawID; }
bool operator!=(const DbgOpID &Other) const { return !(*this == Other); }
@@ -788,7 +789,7 @@ class MLocTracker {
value_type operator*() { return value_type(Idx, ValueMap[LocIdx(Idx)]); }
};
- MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII,
+ LLVM_ABI MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI, const TargetLowering &TLI);
/// Produce location ID number for a Register. Provides some small amount of
@@ -903,7 +904,7 @@ class MLocTracker {
/// Create a LocIdx for an untracked register ID. Initialize it to either an
/// mphi value representing a live-in, or a recent register mask clobber.
- LocIdx trackRegister(unsigned ID);
+ LLVM_ABI LocIdx trackRegister(unsigned ID);
LocIdx lookupOrTrackRegister(unsigned ID) {
LocIdx &Index = LocIDToLocIdx[ID];
@@ -968,7 +969,7 @@ class MLocTracker {
/// Find LocIdx for SpillLoc \p L, creating a new one if it's not tracked.
/// Returns std::nullopt when in scenarios where a spill slot could be
/// tracked, but we would likely run into resource limitations.
- std::optional<SpillLocationNo> getOrTrackSpillLoc(SpillLoc L);
+ LLVM_ABI std::optional<SpillLocationNo> getOrTrackSpillLoc(SpillLoc L);
// Get LocIdx of a spill ID.
LocIdx getSpillMLoc(unsigned SpillID) {
@@ -1342,7 +1343,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// in an MLocTracker. Convert the observations into a per-block transfer
/// function in \p MLocTransfer, suitable for using with the machine value
/// location dataflow problem.
- void
+ LLVM_ABI void
produceMLocTransferFunction(MachineFunction &MF,
SmallVectorImpl<MLocTransferMap> &MLocTransfer,
unsigned MaxNumBlocks);
@@ -1352,7 +1353,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// live-out arrays to the (initialized to zero) multidimensional arrays in
/// \p MInLocs and \p MOutLocs. The outer dimension is indexed by block
/// number, the inner by LocIdx.
- void buildMLocValueMap(MachineFunction &MF, FuncValueTable &MInLocs,
+ LLVM_ABI void buildMLocValueMap(MachineFunction &MF, FuncValueTable &MInLocs,
FuncValueTable &MOutLocs,
SmallVectorImpl<MLocTransferMap> &MLocTransfer);
@@ -1362,7 +1363,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// Install PHI values into the live-in array for each block, according to
/// the IDF of each register.
- void placeMLocPHIs(MachineFunction &MF,
+ LLVM_ABI void placeMLocPHIs(MachineFunction &MF,
SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks,
FuncValueTable &MInLocs,
SmallVectorImpl<MLocTransferMap> &MLocTransfer);
@@ -1422,7 +1423,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// \p AssignBlocks contains the set of blocks that aren't in \p DILoc's
/// scope, but which do contain DBG_VALUEs, which VarLocBasedImpl tracks
/// locations through.
- void buildVLocValueMap(const DILocation *DILoc,
+ LLVM_ABI void buildVLocValueMap(const DILocation *DILoc,
const SmallSet<DebugVariableID, 4> &VarsWeCareAbout,
SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks,
LiveInsT &Output, FuncValueTable &MOutLocs,
@@ -1436,7 +1437,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// \p LiveIn Old live-in value, overwritten with new one if live-in changes.
/// \returns true if any live-ins change value, either from value propagation
/// or PHI elimination.
- bool vlocJoin(MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs,
+ LLVM_ABI bool vlocJoin(MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs,
SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
DbgValue &LiveIn);
@@ -1445,7 +1446,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// into that operand join together.
/// \returns true if a joined location was found for every value that needed
/// to be joined.
- bool
+ LLVM_ABI bool
pickVPHILoc(SmallVectorImpl<DbgOpID> &OutValues, const MachineBasicBlock &MBB,
const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs,
const SmallVectorImpl<const MachineBasicBlock *> &BlockOrders);
@@ -1461,7 +1462,7 @@ class InstrRefBasedLDV : public LDVImpl {
/// Boilerplate computation of some initial sets, artifical blocks and
/// RPOT block ordering.
- void initialSetup(MachineFunction &MF);
+ LLVM_ABI void initialSetup(MachineFunction &MF);
/// Produce a map of the last lexical scope that uses a block, using the
/// scopes DFSOut number. Mapping is block-number to DFSOut.
@@ -1490,7 +1491,7 @@ class InstrRefBasedLDV : public LDVImpl {
public:
/// Default construct and initialize the pass.
- InstrRefBasedLDV();
+ LLVM_ABI InstrRefBasedLDV();
LLVM_DUMP_METHOD
void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const;
diff --git a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.h b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.h
index 27dd2b9aee9af..6dc63c838802c 100644
--- a/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.h
+++ b/llvm/lib/CodeGen/MLRegAllocEvictAdvisor.h
@@ -17,6 +17,7 @@
#include "llvm/Analysis/MLModelRunner.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/SlotIndexes.h"
+#include "llvm/Support/Compiler.h"
#include <map>
namespace llvm {
@@ -32,7 +33,7 @@ struct LRStartEndInfo {
size_t Pos = 0;
};
-void extractInstructionFeatures(
+LLVM_ABI void extractInstructionFeatures(
llvm::SmallVectorImpl<LRStartEndInfo> &LRPosInfo,
MLModelRunner *RegallocRunner, function_ref<int(SlotIndex)> GetOpcode,
function_ref<float(SlotIndex)> GetMBBFreq,
@@ -41,7 +42,7 @@ void extractInstructionFeatures(
const int MBBFreqIndex, const int MBBMappingIndex,
const SlotIndex LastIndex);
-void extractMBBFrequency(const SlotIndex CurrentIndex,
+LLVM_ABI void extractMBBFrequency(const SlotIndex CurrentIndex,
const size_t CurrentInstructionIndex,
std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
function_ref<float(SlotIndex)> GetMBBFreq,
diff --git a/llvm/lib/CodeGen/RegAllocScore.h b/llvm/lib/CodeGen/RegAllocScore.h
index b80adae29f23c..3ef387b61b047 100644
--- a/llvm/lib/CodeGen/RegAllocScore.h
+++ b/llvm/lib/CodeGen/RegAllocScore.h
@@ -16,6 +16,7 @@
#define LLVM_CODEGEN_REGALLOCSCORE_H_
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -52,9 +53,9 @@ class RegAllocScore final {
void onCheapRemat(double Freq) { CheapRematCounts += Freq; }
RegAllocScore &operator+=(const RegAllocScore &Other);
- bool operator==(const RegAllocScore &Other) const;
+ LLVM_ABI bool operator==(const RegAllocScore &Other) const;
bool operator!=(const RegAllocScore &Other) const;
- double getScore() const;
+ LLVM_ABI double getScore() const;
};
/// Calculate a score. When comparing 2 scores for the same function but
@@ -64,7 +65,7 @@ RegAllocScore calculateRegAllocScore(const MachineFunction &MF,
const MachineBlockFrequencyInfo &MBFI);
/// Implementation of the above, which is also more easily unittestable.
-RegAllocScore calculateRegAllocScore(
+LLVM_ABI RegAllocScore calculateRegAllocScore(
const MachineFunction &MF,
llvm::function_ref<double(const MachineBasicBlock &)> GetBBFreq,
llvm::function_ref<bool(const MachineInstr &)> IsTriviallyRematerializable);
>From 2d508e0fe2eaf31d78dc8e1dd48a354458c04c09 Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Wed, 25 Jun 2025 11:57:42 -0700
Subject: [PATCH 2/4] [llvm] export private API so that
DebugInfoLogicalViewTests and DebugInfoDWARFTests build against Windows DLL
---
llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h b/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h
index 79b5df89e3389..0a43d0e066908 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -37,12 +38,12 @@ class DwarfStringPool {
public:
using EntryRef = DwarfStringPoolEntryRef;
- DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix);
+ LLVM_ABI DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix);
- void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection,
+ LLVM_ABI void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection,
MCSymbol *StartSym);
- void emit(AsmPrinter &Asm, MCSection *StrSection,
+ LLVM_ABI void emit(AsmPrinter &Asm, MCSection *StrSection,
MCSection *OffsetSection = nullptr,
bool UseRelativeOffsets = false);
@@ -53,12 +54,12 @@ class DwarfStringPool {
unsigned getNumIndexedStrings() const { return NumIndexedStrings; }
/// Get a reference to an entry in the string pool.
- EntryRef getEntry(AsmPrinter &Asm, StringRef Str);
+ LLVM_ABI EntryRef getEntry(AsmPrinter &Asm, StringRef Str);
/// Same as getEntry, except that you can use EntryRef::getIndex to obtain a
/// unique ID of this entry (e.g., for use in indexed forms like
/// DW_FORM_strx).
- EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str);
+ LLVM_ABI EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str);
};
} // end namespace llvm
>From b01521717378389a443c21aa03e8d20efc3dd7ed Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Wed, 25 Jun 2025 11:58:30 -0700
Subject: [PATCH 3/4] [llvm] export private API so that FileCheckTests builds
against Windows DLL
---
llvm/lib/FileCheck/FileCheckImpl.h | 51 +++++++++++++++---------------
1 file changed, 26 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/FileCheck/FileCheckImpl.h b/llvm/lib/FileCheck/FileCheckImpl.h
index b3cd2af5d57e3..a4a1f0bb1d83a 100644
--- a/llvm/lib/FileCheck/FileCheckImpl.h
+++ b/llvm/lib/FileCheck/FileCheckImpl.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/FileCheck/FileCheck.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/SourceMgr.h"
#include <map>
@@ -88,23 +89,23 @@ struct ExpressionFormat {
/// \returns a wildcard regular expression string that matches any value in
/// the format represented by this instance and no other value, or an error
/// if the format is NoFormat.
- Expected<std::string> getWildcardRegex() const;
+ LLVM_ABI Expected<std::string> getWildcardRegex() const;
/// \returns the string representation of \p Value in the format represented
/// by this instance, or an error if conversion to this format failed or the
/// format is NoFormat.
- Expected<std::string> getMatchingString(APInt Value) const;
+ LLVM_ABI Expected<std::string> getMatchingString(APInt Value) const;
/// \returns the value corresponding to string representation \p StrVal
/// according to the matching format represented by this instance.
- APInt valueFromStringRepr(StringRef StrVal, const SourceMgr &SM) const;
+ LLVM_ABI APInt valueFromStringRepr(StringRef StrVal, const SourceMgr &SM) const;
};
/// Class to represent an overflow error that might result when manipulating a
/// value.
class OverflowError : public ErrorInfo<OverflowError> {
public:
- static char ID;
+ LLVM_ABI static char ID;
std::error_code convertToErrorCode() const override {
return std::make_error_code(std::errc::value_too_large);
@@ -115,10 +116,10 @@ class OverflowError : public ErrorInfo<OverflowError> {
/// Performs operation and \returns its result or an error in case of failure,
/// such as if an overflow occurs.
-Expected<APInt> exprAdd(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
-Expected<APInt> exprSub(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
-Expected<APInt> exprMul(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
-Expected<APInt> exprDiv(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
+LLVM_ABI Expected<APInt> exprAdd(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
+LLVM_ABI Expected<APInt> exprSub(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
+LLVM_ABI Expected<APInt> exprMul(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
+LLVM_ABI Expected<APInt> exprDiv(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
Expected<APInt> exprMax(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
Expected<APInt> exprMin(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
@@ -169,7 +170,7 @@ class UndefVarError : public ErrorInfo<UndefVarError> {
StringRef VarName;
public:
- static char ID;
+ LLVM_ABI static char ID;
UndefVarError(StringRef VarName) : VarName(VarName) {}
@@ -277,7 +278,7 @@ class NumericVariable {
/// Class representing the use of a numeric variable in the AST of an
/// expression.
-class NumericVariableUse : public ExpressionAST {
+class LLVM_ABI NumericVariableUse : public ExpressionAST {
private:
/// Pointer to the class instance for the variable this use is about.
NumericVariable *Variable;
@@ -299,7 +300,7 @@ class NumericVariableUse : public ExpressionAST {
using binop_eval_t = Expected<APInt> (*)(const APInt &, const APInt &, bool &);
/// Class representing a single binary operation in the AST of an expression.
-class BinaryOperation : public ExpressionAST {
+class LLVM_ABI BinaryOperation : public ExpressionAST {
private:
/// Left operand.
std::unique_ptr<ExpressionAST> LeftOperand;
@@ -371,7 +372,7 @@ class Substitution {
virtual Expected<std::string> getResult() const = 0;
};
-class StringSubstitution : public Substitution {
+class LLVM_ABI StringSubstitution : public Substitution {
public:
StringSubstitution(FileCheckPatternContext *Context, StringRef VarName,
size_t InsertIdx)
@@ -382,7 +383,7 @@ class StringSubstitution : public Substitution {
Expected<std::string> getResult() const override;
};
-class NumericSubstitution : public Substitution {
+class LLVM_ABI NumericSubstitution : public Substitution {
private:
/// Pointer to the class representing the expression whose value is to be
/// substituted.
@@ -447,24 +448,24 @@ class FileCheckPatternContext {
public:
/// \returns the value of string variable \p VarName or an error if no such
/// variable has been defined.
- Expected<StringRef> getPatternVarValue(StringRef VarName);
+ LLVM_ABI Expected<StringRef> getPatternVarValue(StringRef VarName);
/// Defines string and numeric variables from definitions given on the
/// command line, passed as a vector of [#]VAR=VAL strings in
/// \p CmdlineDefines. \returns an error list containing diagnostics against
/// \p SM for all definition parsing failures, if any, or Success otherwise.
- Error defineCmdlineVariables(ArrayRef<StringRef> CmdlineDefines,
+ LLVM_ABI Error defineCmdlineVariables(ArrayRef<StringRef> CmdlineDefines,
SourceMgr &SM);
/// Create @LINE pseudo variable. Value is set when pattern are being
/// matched.
- void createLineVariable();
+ LLVM_ABI void createLineVariable();
/// Undefines local variables (variables whose name does not start with a '$'
/// sign), i.e. removes them from GlobalVariableTable and from
/// GlobalNumericVariableTable and also clears the value of numeric
/// variables.
- void clearLocalVars();
+ LLVM_ABI void clearLocalVars();
private:
/// Makes a new numeric variable and registers it for destruction when the
@@ -490,7 +491,7 @@ class ErrorDiagnostic : public ErrorInfo<ErrorDiagnostic> {
SMRange Range;
public:
- static char ID;
+ LLVM_ABI static char ID;
ErrorDiagnostic(SMDiagnostic &&Diag, SMRange Range)
: Diagnostic(Diag), Range(Range) {}
@@ -520,7 +521,7 @@ class ErrorDiagnostic : public ErrorInfo<ErrorDiagnostic> {
class NotFoundError : public ErrorInfo<NotFoundError> {
public:
- static char ID;
+ LLVM_ABI static char ID;
std::error_code convertToErrorCode() const override {
return inconvertibleErrorCode();
@@ -644,7 +645,7 @@ class Pattern {
FileCheckPatternContext *getContext() const { return Context; }
/// \returns whether \p C is a valid first character for a variable name.
- static bool isValidVarNameStart(char C);
+ LLVM_ABI static bool isValidVarNameStart(char C);
/// Parsing information about a variable.
struct VariableProperties {
@@ -657,7 +658,7 @@ class Pattern {
/// is the name of a pseudo variable, or an error holding a diagnostic
/// against \p SM if parsing fail. If parsing was successful, also strips
/// \p Str from the variable name.
- static Expected<VariableProperties> parseVariable(StringRef &Str,
+ LLVM_ABI static Expected<VariableProperties> parseVariable(StringRef &Str,
const SourceMgr &SM);
/// Parses \p Expr for a numeric substitution block at line \p LineNumber,
/// or before input is parsed if \p LineNumber is None. Parameter
@@ -669,7 +670,7 @@ class Pattern {
/// successful, sets \p DefinedNumericVariable to point to the class
/// representing the numeric variable defined in this numeric substitution
/// block, or std::nullopt if this block does not define any variable.
- static Expected<std::unique_ptr<Expression>> parseNumericSubstitutionBlock(
+ LLVM_ABI static Expected<std::unique_ptr<Expression>> parseNumericSubstitutionBlock(
StringRef Expr, std::optional<NumericVariable *> &DefinedNumericVariable,
bool IsLegacyLineExpr, std::optional<size_t> LineNumber,
FileCheckPatternContext *Context, const SourceMgr &SM);
@@ -680,7 +681,7 @@ class Pattern {
/// global options that influence the parsing such as whitespace
/// canonicalization, \p SM provides the SourceMgr used for error reports.
/// \returns true in case of an error, false otherwise.
- bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
+ LLVM_ABI bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM,
const FileCheckRequest &Req);
struct Match {
size_t Pos;
@@ -705,7 +706,7 @@ class Pattern {
/// GlobalNumericVariableTable StringMap in the same class provides the
/// current values of FileCheck numeric variables and is updated if this
/// match defines new numeric values.
- MatchResult match(StringRef Buffer, const SourceMgr &SM) const;
+ LLVM_ABI MatchResult match(StringRef Buffer, const SourceMgr &SM) const;
/// Prints the value of successful substitutions.
void printSubstitutions(const SourceMgr &SM, StringRef Buffer,
SMRange MatchRange, FileCheckDiag::MatchType MatchTy,
@@ -716,7 +717,7 @@ class Pattern {
bool hasVariable() const {
return !(Substitutions.empty() && VariableDefs.empty());
}
- void printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy,
+ LLVM_ABI void printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy,
std::vector<FileCheckDiag> *Diags) const;
Check::FileCheckType getCheckTy() const { return CheckTy; }
>From 8b29d95926e06b460b7e8a297cdffabf7868298c Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Wed, 25 Jun 2025 12:01:07 -0700
Subject: [PATCH 4/4] [llvm] export private API so that VectorizeTests builds
against Windows DLL
---
llvm/lib/Transforms/Vectorize/VPlan.h | 61 ++++++++++---------
.../Transforms/Vectorize/VPlanDominatorTree.h | 1 +
llvm/lib/Transforms/Vectorize/VPlanSLP.h | 4 +-
.../Transforms/Vectorize/VPlanTransforms.h | 9 +--
llvm/lib/Transforms/Vectorize/VPlanValue.h | 3 +-
llvm/lib/Transforms/Vectorize/VPlanVerifier.h | 4 +-
6 files changed, 44 insertions(+), 38 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 972eca1fe8376..aef127968f1ba 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -38,6 +38,7 @@
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/FMF.h"
#include "llvm/IR/Operator.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/InstructionCost.h"
#include <algorithm>
#include <cassert>
@@ -77,7 +78,7 @@ using VPlanPtr = std::unique_ptr<VPlan>;
/// VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
/// A VPBlockBase can be either a VPBasicBlock or a VPRegionBlock.
-class VPBlockBase {
+class LLVM_ABI VPBlockBase {
friend class VPBlockUtils;
const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast).
@@ -384,7 +385,7 @@ class VPBlockBase {
/// and is responsible for deleting its defined values. Single-value
/// recipes must inherit from VPSingleDef instead of inheriting from both
/// VPRecipeBase and VPValue separately.
-class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
+class LLVM_ABI VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
public VPDef,
public VPUser {
friend VPBasicBlock;
@@ -635,7 +636,7 @@ class VPIRFlags {
char AllowContract : 1;
char ApproxFunc : 1;
- FastMathFlagsTy(const FastMathFlags &FMF);
+ LLVM_ABI FastMathFlagsTy(const FastMathFlags &FMF);
};
OperationType OpType;
@@ -787,7 +788,7 @@ class VPIRFlags {
/// Returns true if the recipe has fast-math flags.
bool hasFastMathFlags() const { return OpType == OperationType::FPMathOp; }
- FastMathFlags getFastMathFlags() const;
+ LLVM_ABI FastMathFlags getFastMathFlags() const;
/// Returns true if the recipe has non-negative flag.
bool hasNonNegFlag() const { return OpType == OperationType::NonNegOp; }
@@ -872,7 +873,7 @@ struct VPRecipeWithIRFlags : public VPSingleDefRecipe, public VPIRFlags {
/// Helper to access the operand that contains the unroll part for this recipe
/// after unrolling.
-template <unsigned PartOpIdx> class VPUnrollPartAccessor {
+template <unsigned PartOpIdx> class LLVM_ABI VPUnrollPartAccessor {
protected:
/// Return the VPValue operand containing the unroll part or null if there is
/// no such operand.
@@ -914,7 +915,7 @@ class VPIRMetadata {
/// While as any Recipe it may generate a sequence of IR instructions when
/// executed, these instructions would always form a single-def expression as
/// the VPInstruction is also a single def-use vertex.
-class VPInstruction : public VPRecipeWithIRFlags,
+class LLVM_ABI VPInstruction : public VPRecipeWithIRFlags,
public VPIRMetadata,
public VPUnrollPartAccessor<1> {
friend class VPlanSlp;
@@ -1187,7 +1188,7 @@ class VPPhiAccessors {
#endif
};
-struct VPPhi : public VPInstruction, public VPPhiAccessors {
+struct LLVM_ABI VPPhi : public VPInstruction, public VPPhiAccessors {
VPPhi(ArrayRef<VPValue *> Operands, DebugLoc DL, const Twine &Name = "")
: VPInstruction(Instruction::PHI, Operands, DL, Name) {}
@@ -1308,7 +1309,7 @@ struct VPIRPhi : public VPIRInstruction, public VPPhiAccessors {
/// opcode and operands of the recipe. This recipe covers most of the
/// traditional vectorization cases where each recipe transforms into a
/// vectorized version of itself.
-class VPWidenRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
+class LLVM_ABI VPWidenRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
unsigned Opcode;
public:
@@ -1493,7 +1494,7 @@ class VPWidenIntrinsicRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
};
/// A recipe for widening Call instructions using library calls.
-class VPWidenCallRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
+class LLVM_ABI VPWidenCallRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
/// Variant stores a pointer to the chosen function. There is a 1:1 mapping
/// between a given VF and the chosen vectorized variant, so there will be a
/// different VPlan for each VF with a valid variant.
@@ -1587,7 +1588,7 @@ class VPHistogramRecipe : public VPRecipeBase {
};
/// A recipe for widening select instructions.
-struct VPWidenSelectRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
+struct LLVM_ABI VPWidenSelectRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
VPWidenSelectRecipe(SelectInst &I, ArrayRef<VPValue *> Operands)
: VPRecipeWithIRFlags(VPDef::VPWidenSelectSC, Operands, I),
VPIRMetadata(I) {}
@@ -1631,7 +1632,7 @@ struct VPWidenSelectRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
};
/// A recipe for handling GEP instructions.
-class VPWidenGEPRecipe : public VPRecipeWithIRFlags {
+class LLVM_ABI VPWidenGEPRecipe : public VPRecipeWithIRFlags {
bool isPointerLoopInvariant() const {
return getOperand(0)->isDefinedOutsideLoopRegions();
}
@@ -1817,7 +1818,7 @@ class VPVectorPointerRecipe : public VPRecipeWithIRFlags,
/// * VPWidenPointerInductionRecipe: Generate vector and scalar values for a
/// pointer induction. Produces either a vector PHI per-part or scalar values
/// per-lane based on the canonical induction.
-class VPHeaderPHIRecipe : public VPSingleDefRecipe, public VPPhiAccessors {
+class LLVM_ABI VPHeaderPHIRecipe : public VPSingleDefRecipe, public VPPhiAccessors {
protected:
VPHeaderPHIRecipe(unsigned char VPDefID, Instruction *UnderlyingInstr,
VPValue *Start, DebugLoc DL = DebugLoc::getUnknown())
@@ -2094,7 +2095,7 @@ class VPWidenPointerInductionRecipe : public VPWidenInductionRecipe,
/// recipe is placed in an entry block to a (non-replicate) region, it must have
/// exactly 2 incoming values, the first from the predecessor of the region and
/// the second from the exiting block of the region.
-class VPWidenPHIRecipe : public VPSingleDefRecipe, public VPPhiAccessors {
+class LLVM_ABI VPWidenPHIRecipe : public VPSingleDefRecipe, public VPPhiAccessors {
/// Name to use for the generated IR instruction for the widened phi.
std::string Name;
@@ -2242,7 +2243,7 @@ class VPReductionPHIRecipe : public VPHeaderPHIRecipe,
/// A recipe for vectorizing a phi-node as a sequence of mask-based select
/// instructions.
-class VPBlendRecipe : public VPSingleDefRecipe {
+class LLVM_ABI VPBlendRecipe : public VPSingleDefRecipe {
public:
/// The blend operation is a User of the incoming values and of their
/// respective masks, ordered [I0, M0, I1, M1, I2, M2, ...]. Note that M0 can
@@ -2309,7 +2310,7 @@ class VPBlendRecipe : public VPSingleDefRecipe {
/// or stores into one wide load/store and shuffles. The first operand of a
/// VPInterleave recipe is the address, followed by the stored values, followed
/// by an optional mask.
-class VPInterleaveRecipe : public VPRecipeBase {
+class LLVM_ABI VPInterleaveRecipe : public VPRecipeBase {
const InterleaveGroup<Instruction> *IG;
/// Indicates if the interleave group is in a conditional block and requires a
@@ -2406,7 +2407,7 @@ class VPInterleaveRecipe : public VPRecipeBase {
/// A recipe to represent inloop reduction operations, performing a reduction on
/// a vector operand into a scalar value, and adding the result to a chain.
/// The Operands are {ChainOp, VecOp, [Condition]}.
-class VPReductionRecipe : public VPRecipeWithIRFlags {
+class LLVM_ABI VPReductionRecipe : public VPRecipeWithIRFlags {
/// The recurrence kind for the reduction in question.
RecurKind RdxKind;
bool IsOrdered;
@@ -2576,7 +2577,7 @@ class VPPartialReductionRecipe : public VPReductionRecipe {
/// intrinsics, performing a reduction on a vector operand with the explicit
/// vector length (EVL) into a scalar value, and adding the result to a chain.
/// The Operands are {ChainOp, VecOp, EVL, [Condition]}.
-class VPReductionEVLRecipe : public VPReductionRecipe {
+class LLVM_ABI VPReductionEVLRecipe : public VPReductionRecipe {
public:
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp,
DebugLoc DL = {})
@@ -2803,7 +2804,7 @@ class VPMulAccumulateReductionRecipe : public VPReductionRecipe {
/// copies of the original scalar type, one per lane, instead of producing a
/// single copy of widened type for all lanes. If the instruction is known to be
/// a single scalar, only one copy, per lane zero, will be generated.
-class VPReplicateRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
+class LLVM_ABI VPReplicateRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
/// Indicator if only a single replica per lane is needed.
bool IsSingleScalar;
@@ -2881,7 +2882,7 @@ class VPReplicateRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
};
/// A recipe for generating conditional branches on the bits of a mask.
-class VPBranchOnMaskRecipe : public VPRecipeBase {
+class LLVM_ABI VPBranchOnMaskRecipe : public VPRecipeBase {
public:
VPBranchOnMaskRecipe(VPValue *BlockInMask, DebugLoc DL)
: VPRecipeBase(VPDef::VPBranchOnMaskSC, {BlockInMask}, DL) {}
@@ -2922,7 +2923,7 @@ class VPBranchOnMaskRecipe : public VPRecipeBase {
/// order to merge values that are set under such a branch and feed their uses.
/// The phi nodes can be scalar or vector depending on the users of the value.
/// This recipe works in concert with VPBranchOnMaskRecipe.
-class VPPredInstPHIRecipe : public VPSingleDefRecipe {
+class LLVM_ABI VPPredInstPHIRecipe : public VPSingleDefRecipe {
public:
/// Construct a VPPredInstPHIRecipe given \p PredInst whose value needs a phi
/// nodes after merging back from a Branch-on-Mask.
@@ -2963,7 +2964,7 @@ class VPPredInstPHIRecipe : public VPSingleDefRecipe {
/// A common base class for widening memory operations. An optional mask can be
/// provided as the last operand.
-class VPWidenMemoryRecipe : public VPRecipeBase, public VPIRMetadata {
+class LLVM_ABI VPWidenMemoryRecipe : public VPRecipeBase, public VPIRMetadata {
protected:
Instruction &Ingredient;
@@ -3044,7 +3045,7 @@ class VPWidenMemoryRecipe : public VPRecipeBase, public VPIRMetadata {
/// A recipe for widening load operations, using the address to load from and an
/// optional mask.
-struct VPWidenLoadRecipe final : public VPWidenMemoryRecipe, public VPValue {
+struct LLVM_ABI VPWidenLoadRecipe final : public VPWidenMemoryRecipe, public VPValue {
VPWidenLoadRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask,
bool Consecutive, bool Reverse,
const VPIRMetadata &Metadata, DebugLoc DL)
@@ -3123,7 +3124,7 @@ struct VPWidenLoadEVLRecipe final : public VPWidenMemoryRecipe, public VPValue {
/// A recipe for widening store operations, using the stored value, the address
/// to store to and an optional mask.
-struct VPWidenStoreRecipe final : public VPWidenMemoryRecipe {
+struct LLVM_ABI VPWidenStoreRecipe final : public VPWidenMemoryRecipe {
VPWidenStoreRecipe(StoreInst &Store, VPValue *Addr, VPValue *StoredVal,
VPValue *Mask, bool Consecutive, bool Reverse,
const VPIRMetadata &Metadata, DebugLoc DL)
@@ -3483,7 +3484,7 @@ class VPDerivedIVRecipe : public VPSingleDefRecipe {
/// A recipe for handling phi nodes of integer and floating-point inductions,
/// producing their scalar values.
-class VPScalarIVStepsRecipe : public VPRecipeWithIRFlags,
+class LLVM_ABI VPScalarIVStepsRecipe : public VPRecipeWithIRFlags,
public VPUnrollPartAccessor<3> {
Instruction::BinaryOps InductionOpcode;
@@ -3593,7 +3594,7 @@ struct CastInfo<VPPhiAccessors, const VPRecipeBase *>
/// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
/// holds a sequence of zero or more VPRecipe's each representing a sequence of
/// output IR instructions. All PHI-like recipes must come before any non-PHI recipes.
-class VPBasicBlock : public VPBlockBase {
+class LLVM_ABI VPBasicBlock : public VPBlockBase {
friend class VPlan;
/// Use VPlan::createVPBasicBlock to create VPBasicBlocks.
@@ -3781,7 +3782,7 @@ class VPIRBasicBlock : public VPBasicBlock {
/// this replication indicator helps to keep a single model for multiple
/// candidate VF's. The actual replication takes place only once the desired VF
/// and UF have been determined.
-class VPRegionBlock : public VPBlockBase {
+class LLVM_ABI VPRegionBlock : public VPBlockBase {
friend class VPlan;
/// Hold the Single Entry of the SESE region modelled by the VPRegionBlock.
@@ -3970,7 +3971,7 @@ class VPlan {
TripCount = TC;
}
- ~VPlan();
+ LLVM_ABI ~VPlan();
void setEntry(VPBasicBlock *VPBB) {
Entry = VPBB;
@@ -4000,8 +4001,8 @@ class VPlan {
}
/// Returns the VPRegionBlock of the vector loop.
- VPRegionBlock *getVectorLoopRegion();
- const VPRegionBlock *getVectorLoopRegion() const;
+ LLVM_ABI VPRegionBlock *getVectorLoopRegion();
+ LLVM_ABI const VPRegionBlock *getVectorLoopRegion() const;
/// Returns the 'middle' block of the plan, that is the block that selects
/// whether to execute the scalar tail loop or the exit block from the loop
@@ -4240,7 +4241,7 @@ class VPlan {
/// instructions in \p IRBB, except its terminator which is managed by the
/// successors of the block in VPlan. The returned block is owned by the VPlan
/// and deleted once the VPlan is destroyed.
- VPIRBasicBlock *createVPIRBasicBlock(BasicBlock *IRBB);
+ LLVM_ABI VPIRBasicBlock *createVPIRBasicBlock(BasicBlock *IRBB);
/// Returns true if the VPlan is based on a loop with an early exit. That is
/// the case if the VPlan has either more than one exit block or a single exit
diff --git a/llvm/lib/Transforms/Vectorize/VPlanDominatorTree.h b/llvm/lib/Transforms/Vectorize/VPlanDominatorTree.h
index 995c6b8b2c2fb..577432fb9a865 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanDominatorTree.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanDominatorTree.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/GenericDomTreeConstruction.h"
namespace llvm {
diff --git a/llvm/lib/Transforms/Vectorize/VPlanSLP.h b/llvm/lib/Transforms/Vectorize/VPlanSLP.h
index 157e78363e55f..20d365b9bbbcb 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanSLP.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanSLP.h
@@ -47,7 +47,7 @@ class VPInterleavedAccessInfo {
InterleavedAccessInfo &IAI);
public:
- VPInterleavedAccessInfo(VPlan &Plan, InterleavedAccessInfo &IAI);
+ LLVM_ABI VPInterleavedAccessInfo(VPlan &Plan, InterleavedAccessInfo &IAI);
VPInterleavedAccessInfo(const VPInterleavedAccessInfo &) = delete;
VPInterleavedAccessInfo &operator=(const VPInterleavedAccessInfo &) = delete;
@@ -132,7 +132,7 @@ class VPlanSlp {
/// Tries to build an SLP tree rooted at \p Operands and returns a
/// VPInstruction combining \p Operands, if they can be combined.
- VPInstruction *buildGraph(ArrayRef<VPValue *> Operands);
+ LLVM_ABI VPInstruction *buildGraph(ArrayRef<VPValue *> Operands);
/// Return the width of the widest combined bundle in bits.
unsigned getWidestBundleBits() const { return WidestBundleBits; }
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
index 7e51c05d1b5b5..c4f411d345e49 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
@@ -17,6 +17,7 @@
#include "VPlanVerifier.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -53,7 +54,7 @@ struct VPlanTransforms {
verifyVPlanIsValid(Plan);
}
- static std::unique_ptr<VPlan> buildPlainCFG(Loop *TheLoop, LoopInfo &LI);
+ LLVM_ABI static std::unique_ptr<VPlan> buildPlainCFG(Loop *TheLoop, LoopInfo &LI);
/// Prepare the plan for vectorization. It will introduce a dedicated
/// VPBasicBlock for the vector pre-header as well as a VPBasicBlock as exit
@@ -63,7 +64,7 @@ struct VPlanTransforms {
/// blocks. \p InductionTy is the type of the canonical induction and used for
/// related values, like the trip count expression. It also creates a VPValue
/// expression for the original trip count.
- static void prepareForVectorization(VPlan &Plan, Type *InductionTy,
+ LLVM_ABI static void prepareForVectorization(VPlan &Plan, Type *InductionTy,
PredicatedScalarEvolution &PSE,
bool RequiresScalarEpilogueCheck,
bool TailFolded, Loop *TheLoop,
@@ -72,12 +73,12 @@ struct VPlanTransforms {
/// Replace loops in \p Plan's flat CFG with VPRegionBlocks, turning \p Plan's
/// flat CFG into a hierarchical CFG.
- static void createLoopRegions(VPlan &Plan);
+ LLVM_ABI static void createLoopRegions(VPlan &Plan);
/// Replaces the VPInstructions in \p Plan with corresponding
/// widen recipes. Returns false if any VPInstructions could not be converted
/// to a wide recipe if needed.
- static bool tryToConvertVPInstructionsToVPRecipes(
+ LLVM_ABI static bool tryToConvertVPInstructionsToVPRecipes(
VPlanPtr &Plan,
function_ref<const InductionDescriptor *(PHINode *)>
GetIntOrFpInductionDescriptor,
diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h
index a0d3dc9b934cc..5308daf4fd702 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanValue.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -44,7 +45,7 @@ class VPPhiAccessors;
// flow into, within and out of the VPlan. VPValues can stand for live-ins
// coming from the input IR and instructions which VPlan will generate if
// executed.
-class VPValue {
+class LLVM_ABI VPValue {
friend class VPDef;
friend struct VPDoubleValueDef;
friend class VPInterleaveRecipe;
diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.h b/llvm/lib/Transforms/Vectorize/VPlanVerifier.h
index 34a2fa2bab1e5..68db03dd150e7 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.h
@@ -24,6 +24,8 @@
#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANVERIFIER_H
#define LLVM_TRANSFORMS_VECTORIZE_VPLANVERIFIER_H
+#include "llvm/Support/Compiler.h"
+
namespace llvm {
class VPlan;
@@ -35,7 +37,7 @@ class VPlan;
/// 2. all phi-like recipes must be at the beginning of a block, with no other
/// recipes in between. Note that currently there is still an exception for
/// VPBlendRecipes.
-bool verifyVPlanIsValid(const VPlan &Plan, bool VerifyLate = false);
+LLVM_ABI bool verifyVPlanIsValid(const VPlan &Plan, bool VerifyLate = false);
} // namespace llvm
More information about the llvm-commits
mailing list