[llvm] export private symbols needed by unittests (#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. Based on the discussion of option 2 in
#145448, this option is preferable.

## Overview
* Adds a new `LLVM_ABI_FOR_TEST` export macro, which is currently just
an alias for `LLVM_ABI`.
* Annotates the sub-set of symbols under `llvm/lib` that are required to
get unit tests building using the new macro.
This commit is contained in:
Andrew Rogers 2025-07-10 08:20:09 -07:00 committed by GitHub
parent 9ef0a886e6
commit 4e2efa55c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 166 additions and 124 deletions

View File

@ -171,6 +171,11 @@
/// for both functions and classes. On windows its turned in to dllimport for
/// library consumers, for other platforms its a default visibility attribute.
///
/// LLVM_ABI_FOR_TEST is for annotating symbols that are only exported because
/// they are imported from a test. These symbols are not technically part of the
/// LLVM public interface and could be conditionally excluded when not building
/// tests in the future.
///
#ifndef LLVM_ABI_GENERATING_ANNOTATIONS
// Marker to add to classes or functions in public headers that should not have
// export macros added to them by the clang tool
@ -210,6 +215,7 @@
#define LLVM_EXPORT_TEMPLATE
#define LLVM_ABI_EXPORT
#endif
#define LLVM_ABI_FOR_TEST LLVM_ABI
#endif
#if defined(__GNUC__)

View File

@ -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 @@ public:
uint64_t computeCUSignature(StringRef DWOName, const DIE &Die);
/// Computes the type signature.
uint64_t computeTypeSignature(const DIE &Die);
LLVM_ABI_FOR_TEST uint64_t computeTypeSignature(const DIE &Die);
// Helper routines to process parts of a DIE.
private:

View File

@ -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,14 +38,16 @@ class DwarfStringPool {
public:
using EntryRef = DwarfStringPoolEntryRef;
DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix);
LLVM_ABI_FOR_TEST DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm,
StringRef Prefix);
void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection,
MCSymbol *StartSym);
LLVM_ABI_FOR_TEST void emitStringOffsetsTableHeader(AsmPrinter &Asm,
MCSection *OffsetSection,
MCSymbol *StartSym);
void emit(AsmPrinter &Asm, MCSection *StrSection,
MCSection *OffsetSection = nullptr,
bool UseRelativeOffsets = false);
LLVM_ABI_FOR_TEST void emit(AsmPrinter &Asm, MCSection *StrSection,
MCSection *OffsetSection = nullptr,
bool UseRelativeOffsets = false);
bool empty() const { return Pool.empty(); }
@ -53,12 +56,12 @@ public:
unsigned getNumIndexedStrings() const { return NumIndexedStrings; }
/// Get a reference to an entry in the string pool.
EntryRef getEntry(AsmPrinter &Asm, StringRef Str);
LLVM_ABI_FOR_TEST 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_FOR_TEST EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str);
};
} // end namespace llvm

View File

@ -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 @@ public:
.str();
}
static ValueIDNum EmptyValue;
static ValueIDNum TombstoneValue;
LLVM_ABI_FOR_TEST static ValueIDNum EmptyValue;
LLVM_ABI_FOR_TEST 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_FOR_TEST static DbgOpID UndefID;
bool operator==(const DbgOpID &Other) const { return RawID == Other.RawID; }
bool operator!=(const DbgOpID &Other) const { return !(*this == Other); }
@ -788,8 +789,9 @@ public:
value_type operator*() { return value_type(Idx, ValueMap[LocIdx(Idx)]); }
};
MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI, const TargetLowering &TLI);
LLVM_ABI_FOR_TEST MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
const TargetLowering &TLI);
/// Produce location ID number for a Register. Provides some small amount of
/// type safety.
@ -903,7 +905,7 @@ public:
/// 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_FOR_TEST LocIdx trackRegister(unsigned ID);
LocIdx lookupOrTrackRegister(unsigned ID) {
LocIdx &Index = LocIDToLocIdx[ID];
@ -968,7 +970,8 @@ public:
/// 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_FOR_TEST std::optional<SpillLocationNo>
getOrTrackSpillLoc(SpillLoc L);
// Get LocIdx of a spill ID.
LocIdx getSpillMLoc(unsigned SpillID) {
@ -1342,7 +1345,7 @@ private:
/// 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_FOR_TEST void
produceMLocTransferFunction(MachineFunction &MF,
SmallVectorImpl<MLocTransferMap> &MLocTransfer,
unsigned MaxNumBlocks);
@ -1352,9 +1355,10 @@ private:
/// 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,
FuncValueTable &MOutLocs,
SmallVectorImpl<MLocTransferMap> &MLocTransfer);
LLVM_ABI_FOR_TEST void
buildMLocValueMap(MachineFunction &MF, FuncValueTable &MInLocs,
FuncValueTable &MOutLocs,
SmallVectorImpl<MLocTransferMap> &MLocTransfer);
/// Examine the stack indexes (i.e. offsets within the stack) to find the
/// basic units of interference -- like reg units, but for the stack.
@ -1362,10 +1366,9 @@ private:
/// Install PHI values into the live-in array for each block, according to
/// the IDF of each register.
void placeMLocPHIs(MachineFunction &MF,
SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks,
FuncValueTable &MInLocs,
SmallVectorImpl<MLocTransferMap> &MLocTransfer);
LLVM_ABI_FOR_TEST void placeMLocPHIs(
MachineFunction &MF, SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks,
FuncValueTable &MInLocs, SmallVectorImpl<MLocTransferMap> &MLocTransfer);
/// Propagate variable values to blocks in the common case where there's
/// only one value assigned to the variable. This function has better
@ -1422,12 +1425,13 @@ private:
/// \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,
const SmallSet<DebugVariableID, 4> &VarsWeCareAbout,
SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks,
LiveInsT &Output, FuncValueTable &MOutLocs,
FuncValueTable &MInLocs,
SmallVectorImpl<VLocTracker> &AllTheVLocs);
LLVM_ABI_FOR_TEST void
buildVLocValueMap(const DILocation *DILoc,
const SmallSet<DebugVariableID, 4> &VarsWeCareAbout,
SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks,
LiveInsT &Output, FuncValueTable &MOutLocs,
FuncValueTable &MInLocs,
SmallVectorImpl<VLocTracker> &AllTheVLocs);
/// Attempt to eliminate un-necessary PHIs on entry to a block. Examines the
/// live-in values coming from predecessors live-outs, and replaces any PHIs
@ -1436,16 +1440,17 @@ private:
/// \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,
SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
DbgValue &LiveIn);
LLVM_ABI_FOR_TEST bool
vlocJoin(MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs,
SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
DbgValue &LiveIn);
/// For the given block and live-outs feeding into it, try to find
/// machine locations for each debug operand where all the values feeding
/// into that operand join together.
/// \returns true if a joined location was found for every value that needed
/// to be joined.
bool
LLVM_ABI_FOR_TEST bool
pickVPHILoc(SmallVectorImpl<DbgOpID> &OutValues, const MachineBasicBlock &MBB,
const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs,
const SmallVectorImpl<const MachineBasicBlock *> &BlockOrders);
@ -1461,7 +1466,7 @@ private:
/// Boilerplate computation of some initial sets, artifical blocks and
/// RPOT block ordering.
void initialSetup(MachineFunction &MF);
LLVM_ABI_FOR_TEST 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 +1495,7 @@ private:
public:
/// Default construct and initialize the pass.
InstrRefBasedLDV();
LLVM_ABI_FOR_TEST InstrRefBasedLDV();
LLVM_DUMP_METHOD
void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const;

View File

@ -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_FOR_TEST void extractInstructionFeatures(
llvm::SmallVectorImpl<LRStartEndInfo> &LRPosInfo,
MLModelRunner *RegallocRunner, function_ref<int(SlotIndex)> GetOpcode,
function_ref<float(SlotIndex)> GetMBBFreq,
@ -41,13 +42,12 @@ void extractInstructionFeatures(
const int MBBFreqIndex, const int MBBMappingIndex,
const SlotIndex LastIndex);
void extractMBBFrequency(const SlotIndex CurrentIndex,
const size_t CurrentInstructionIndex,
std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
function_ref<float(SlotIndex)> GetMBBFreq,
MachineBasicBlock *CurrentMBBReference,
MLModelRunner *RegallocRunner, const int MBBFreqIndex,
const int MBBMappingIndex);
LLVM_ABI_FOR_TEST void extractMBBFrequency(
const SlotIndex CurrentIndex, const size_t CurrentInstructionIndex,
std::map<MachineBasicBlock *, size_t> &VisitedMBBs,
function_ref<float(SlotIndex)> GetMBBFreq,
MachineBasicBlock *CurrentMBBReference, MLModelRunner *RegallocRunner,
const int MBBFreqIndex, const int MBBMappingIndex);
// This is the maximum number of interfererring ranges. That's the number of
// distinct AllocationOrder values, which comes from MCRegisterClass::RegsSize.

View File

@ -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 @@ public:
void onCheapRemat(double Freq) { CheapRematCounts += Freq; }
RegAllocScore &operator+=(const RegAllocScore &Other);
bool operator==(const RegAllocScore &Other) const;
LLVM_ABI_FOR_TEST bool operator==(const RegAllocScore &Other) const;
bool operator!=(const RegAllocScore &Other) const;
double getScore() const;
LLVM_ABI_FOR_TEST 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_FOR_TEST RegAllocScore calculateRegAllocScore(
const MachineFunction &MF,
llvm::function_ref<double(const MachineBasicBlock &)> GetBBFreq,
llvm::function_ref<bool(const MachineInstr &)> IsTriviallyRematerializable);

View File

@ -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,24 @@ public:
/// \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_FOR_TEST 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_FOR_TEST 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_FOR_TEST 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_FOR_TEST static char ID;
std::error_code convertToErrorCode() const override {
return std::make_error_code(std::errc::value_too_large);
@ -115,10 +117,14 @@ public:
/// 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_FOR_TEST Expected<APInt> exprAdd(const APInt &Lhs, const APInt &Rhs,
bool &Overflow);
LLVM_ABI_FOR_TEST Expected<APInt> exprSub(const APInt &Lhs, const APInt &Rhs,
bool &Overflow);
LLVM_ABI_FOR_TEST Expected<APInt> exprMul(const APInt &Lhs, const APInt &Rhs,
bool &Overflow);
LLVM_ABI_FOR_TEST 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 +175,7 @@ private:
StringRef VarName;
public:
static char ID;
LLVM_ABI_FOR_TEST static char ID;
UndefVarError(StringRef VarName) : VarName(VarName) {}
@ -277,7 +283,7 @@ public:
/// Class representing the use of a numeric variable in the AST of an
/// expression.
class NumericVariableUse : public ExpressionAST {
class LLVM_ABI_FOR_TEST NumericVariableUse : public ExpressionAST {
private:
/// Pointer to the class instance for the variable this use is about.
NumericVariable *Variable;
@ -299,7 +305,7 @@ public:
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_FOR_TEST BinaryOperation : public ExpressionAST {
private:
/// Left operand.
std::unique_ptr<ExpressionAST> LeftOperand;
@ -377,7 +383,7 @@ public:
virtual Expected<std::string> getResultForDiagnostics() const = 0;
};
class StringSubstitution : public Substitution {
class LLVM_ABI_FOR_TEST StringSubstitution : public Substitution {
public:
StringSubstitution(FileCheckPatternContext *Context, StringRef VarName,
size_t InsertIdx)
@ -393,7 +399,7 @@ public:
Expected<std::string> getResultForDiagnostics() const override;
};
class NumericSubstitution : public Substitution {
class LLVM_ABI_FOR_TEST NumericSubstitution : public Substitution {
private:
/// Pointer to the class representing the expression whose value is to be
/// substituted.
@ -463,24 +469,24 @@ private:
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_FOR_TEST 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,
SourceMgr &SM);
LLVM_ABI_FOR_TEST Error
defineCmdlineVariables(ArrayRef<StringRef> CmdlineDefines, SourceMgr &SM);
/// Create @LINE pseudo variable. Value is set when pattern are being
/// matched.
void createLineVariable();
LLVM_ABI_FOR_TEST 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_FOR_TEST void clearLocalVars();
private:
/// Makes a new numeric variable and registers it for destruction when the
@ -506,7 +512,7 @@ private:
SMRange Range;
public:
static char ID;
LLVM_ABI_FOR_TEST static char ID;
ErrorDiagnostic(SMDiagnostic &&Diag, SMRange Range)
: Diagnostic(Diag), Range(Range) {}
@ -536,7 +542,7 @@ public:
class NotFoundError : public ErrorInfo<NotFoundError> {
public:
static char ID;
LLVM_ABI_FOR_TEST static char ID;
std::error_code convertToErrorCode() const override {
return inconvertibleErrorCode();
@ -660,7 +666,7 @@ public:
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_FOR_TEST static bool isValidVarNameStart(char C);
/// Parsing information about a variable.
struct VariableProperties {
@ -673,8 +679,8 @@ public:
/// 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,
const SourceMgr &SM);
LLVM_ABI_FOR_TEST 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
/// \p IsLegacyLineExpr indicates whether \p Expr should be a legacy @LINE
@ -685,7 +691,8 @@ public:
/// 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_FOR_TEST 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);
@ -696,8 +703,9 @@ public:
/// 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,
const FileCheckRequest &Req);
LLVM_ABI_FOR_TEST bool parsePattern(StringRef PatternStr, StringRef Prefix,
SourceMgr &SM,
const FileCheckRequest &Req);
struct Match {
size_t Pos;
size_t Len;
@ -721,7 +729,8 @@ public:
/// 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_FOR_TEST 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,
@ -732,8 +741,9 @@ public:
bool hasVariable() const {
return !(Substitutions.empty() && VariableDefs.empty());
}
void printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy,
std::vector<FileCheckDiag> *Diags) const;
LLVM_ABI_FOR_TEST void
printVariableDefs(const SourceMgr &SM, FileCheckDiag::MatchType MatchTy,
std::vector<FileCheckDiag> *Diags) const;
Check::FileCheckType getCheckTy() const { return CheckTy; }

View File

@ -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_FOR_TEST VPBlockBase {
friend class VPBlockUtils;
const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast).
@ -384,9 +385,10 @@ public:
/// 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>,
public VPDef,
public VPUser {
class LLVM_ABI_FOR_TEST VPRecipeBase
: public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
public VPDef,
public VPUser {
friend VPBasicBlock;
friend class VPBlockUtils;
@ -634,7 +636,7 @@ private:
char AllowContract : 1;
char ApproxFunc : 1;
FastMathFlagsTy(const FastMathFlags &FMF);
LLVM_ABI_FOR_TEST FastMathFlagsTy(const FastMathFlags &FMF);
};
OperationType OpType;
@ -786,7 +788,7 @@ public:
/// Returns true if the recipe has fast-math flags.
bool hasFastMathFlags() const { return OpType == OperationType::FPMathOp; }
FastMathFlags getFastMathFlags() const;
LLVM_ABI_FOR_TEST FastMathFlags getFastMathFlags() const;
/// Returns true if the recipe has non-negative flag.
bool hasNonNegFlag() const { return OpType == OperationType::NonNegOp; }
@ -870,7 +872,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_FOR_TEST VPUnrollPartAccessor {
protected:
/// Return the VPValue operand containing the unroll part or null if there is
/// no such operand.
@ -912,9 +914,9 @@ public:
/// 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,
public VPIRMetadata,
public VPUnrollPartAccessor<1> {
class LLVM_ABI_FOR_TEST VPInstruction : public VPRecipeWithIRFlags,
public VPIRMetadata,
public VPUnrollPartAccessor<1> {
friend class VPlanSlp;
public:
@ -1198,7 +1200,7 @@ public:
#endif
};
struct VPPhi : public VPInstruction, public VPPhiAccessors {
struct LLVM_ABI_FOR_TEST VPPhi : public VPInstruction, public VPPhiAccessors {
VPPhi(ArrayRef<VPValue *> Operands, DebugLoc DL, const Twine &Name = "")
: VPInstruction(Instruction::PHI, Operands, DL, Name) {}
@ -1319,7 +1321,8 @@ protected:
/// 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_FOR_TEST VPWidenRecipe : public VPRecipeWithIRFlags,
public VPIRMetadata {
unsigned Opcode;
public:
@ -1504,7 +1507,8 @@ public:
};
/// A recipe for widening Call instructions using library calls.
class VPWidenCallRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
class LLVM_ABI_FOR_TEST 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.
@ -1598,7 +1602,8 @@ public:
};
/// A recipe for widening select instructions.
struct VPWidenSelectRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
struct LLVM_ABI_FOR_TEST VPWidenSelectRecipe : public VPRecipeWithIRFlags,
public VPIRMetadata {
VPWidenSelectRecipe(SelectInst &I, ArrayRef<VPValue *> Operands)
: VPRecipeWithIRFlags(VPDef::VPWidenSelectSC, Operands, I),
VPIRMetadata(I) {}
@ -1642,7 +1647,7 @@ struct VPWidenSelectRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
};
/// A recipe for handling GEP instructions.
class VPWidenGEPRecipe : public VPRecipeWithIRFlags {
class LLVM_ABI_FOR_TEST VPWidenGEPRecipe : public VPRecipeWithIRFlags {
bool isPointerLoopInvariant() const {
return getOperand(0)->isDefinedOutsideLoopRegions();
}
@ -1835,7 +1840,8 @@ public:
/// * 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_FOR_TEST VPHeaderPHIRecipe : public VPSingleDefRecipe,
public VPPhiAccessors {
protected:
VPHeaderPHIRecipe(unsigned char VPDefID, Instruction *UnderlyingInstr,
VPValue *Start, DebugLoc DL = DebugLoc::getUnknown())
@ -2112,7 +2118,8 @@ public:
/// 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_FOR_TEST VPWidenPHIRecipe : public VPSingleDefRecipe,
public VPPhiAccessors {
/// Name to use for the generated IR instruction for the widened phi.
std::string Name;
@ -2257,7 +2264,7 @@ public:
/// A recipe for vectorizing a phi-node as a sequence of mask-based select
/// instructions.
class VPBlendRecipe : public VPSingleDefRecipe {
class LLVM_ABI_FOR_TEST 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
@ -2324,7 +2331,7 @@ public:
/// 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_FOR_TEST VPInterleaveRecipe : public VPRecipeBase {
const InterleaveGroup<Instruction> *IG;
/// Indicates if the interleave group is in a conditional block and requires a
@ -2424,7 +2431,7 @@ public:
/// 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_FOR_TEST VPReductionRecipe : public VPRecipeWithIRFlags {
/// The recurrence kind for the reduction in question.
RecurKind RdxKind;
bool IsOrdered;
@ -2570,7 +2577,7 @@ public:
/// 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_FOR_TEST VPReductionEVLRecipe : public VPReductionRecipe {
public:
VPReductionEVLRecipe(VPReductionRecipe &R, VPValue &EVL, VPValue *CondOp,
DebugLoc DL = {})
@ -2613,7 +2620,8 @@ public:
/// 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_FOR_TEST VPReplicateRecipe : public VPRecipeWithIRFlags,
public VPIRMetadata {
/// Indicator if only a single replica per lane is needed.
bool IsSingleScalar;
@ -2691,7 +2699,7 @@ public:
};
/// A recipe for generating conditional branches on the bits of a mask.
class VPBranchOnMaskRecipe : public VPRecipeBase {
class LLVM_ABI_FOR_TEST VPBranchOnMaskRecipe : public VPRecipeBase {
public:
VPBranchOnMaskRecipe(VPValue *BlockInMask, DebugLoc DL)
: VPRecipeBase(VPDef::VPBranchOnMaskSC, {BlockInMask}, DL) {}
@ -2848,7 +2856,7 @@ public:
/// order to merge values that are set under such a branch and feed their uses.
/// The phi nodes can be scalar or vector depending on the users of the value.
/// This recipe works in concert with VPBranchOnMaskRecipe.
class VPPredInstPHIRecipe : public VPSingleDefRecipe {
class LLVM_ABI_FOR_TEST VPPredInstPHIRecipe : public VPSingleDefRecipe {
public:
/// Construct a VPPredInstPHIRecipe given \p PredInst whose value needs a phi
/// nodes after merging back from a Branch-on-Mask.
@ -2889,7 +2897,8 @@ public:
/// 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_FOR_TEST VPWidenMemoryRecipe : public VPRecipeBase,
public VPIRMetadata {
protected:
Instruction &Ingredient;
@ -2970,7 +2979,8 @@ public:
/// 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_FOR_TEST VPWidenLoadRecipe final : public VPWidenMemoryRecipe,
public VPValue {
VPWidenLoadRecipe(LoadInst &Load, VPValue *Addr, VPValue *Mask,
bool Consecutive, bool Reverse,
const VPIRMetadata &Metadata, DebugLoc DL)
@ -3049,7 +3059,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_FOR_TEST VPWidenStoreRecipe final : public VPWidenMemoryRecipe {
VPWidenStoreRecipe(StoreInst &Store, VPValue *Addr, VPValue *StoredVal,
VPValue *Mask, bool Consecutive, bool Reverse,
const VPIRMetadata &Metadata, DebugLoc DL)
@ -3409,8 +3419,8 @@ public:
/// A recipe for handling phi nodes of integer and floating-point inductions,
/// producing their scalar values.
class VPScalarIVStepsRecipe : public VPRecipeWithIRFlags,
public VPUnrollPartAccessor<3> {
class LLVM_ABI_FOR_TEST VPScalarIVStepsRecipe : public VPRecipeWithIRFlags,
public VPUnrollPartAccessor<3> {
Instruction::BinaryOps InductionOpcode;
public:
@ -3519,7 +3529,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_FOR_TEST VPBasicBlock : public VPBlockBase {
friend class VPlan;
/// Use VPlan::createVPBasicBlock to create VPBasicBlocks.
@ -3707,7 +3717,7 @@ public:
/// 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_FOR_TEST VPRegionBlock : public VPBlockBase {
friend class VPlan;
/// Hold the Single Entry of the SESE region modelled by the VPRegionBlock.
@ -3896,7 +3906,7 @@ public:
TripCount = TC;
}
~VPlan();
LLVM_ABI_FOR_TEST ~VPlan();
void setEntry(VPBasicBlock *VPBB) {
Entry = VPBB;
@ -3926,8 +3936,8 @@ public:
}
/// Returns the VPRegionBlock of the vector loop.
VPRegionBlock *getVectorLoopRegion();
const VPRegionBlock *getVectorLoopRegion() const;
LLVM_ABI_FOR_TEST VPRegionBlock *getVectorLoopRegion();
LLVM_ABI_FOR_TEST 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
@ -4166,7 +4176,7 @@ public:
/// 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_FOR_TEST 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

View File

@ -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 {

View File

@ -47,7 +47,8 @@ class VPInterleavedAccessInfo {
InterleavedAccessInfo &IAI);
public:
VPInterleavedAccessInfo(VPlan &Plan, InterleavedAccessInfo &IAI);
LLVM_ABI_FOR_TEST VPInterleavedAccessInfo(VPlan &Plan,
InterleavedAccessInfo &IAI);
VPInterleavedAccessInfo(const VPInterleavedAccessInfo &) = delete;
VPInterleavedAccessInfo &operator=(const VPInterleavedAccessInfo &) = delete;
@ -132,7 +133,7 @@ public:
/// 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_FOR_TEST VPInstruction *buildGraph(ArrayRef<VPValue *> Operands);
/// Return the width of the widest combined bundle in bits.
unsigned getWidestBundleBits() const { return WidestBundleBits; }

View File

@ -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,8 @@ struct VPlanTransforms {
verifyVPlanIsValid(Plan);
}
static std::unique_ptr<VPlan> buildPlainCFG(Loop *TheLoop, LoopInfo &LI);
LLVM_ABI_FOR_TEST 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,16 +65,14 @@ 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,
PredicatedScalarEvolution &PSE,
bool RequiresScalarEpilogueCheck,
bool TailFolded, Loop *TheLoop,
DebugLoc IVDL, bool HasUncountableExit,
VFRange &Range);
LLVM_ABI_FOR_TEST static void prepareForVectorization(
VPlan &Plan, Type *InductionTy, PredicatedScalarEvolution &PSE,
bool RequiresScalarEpilogueCheck, bool TailFolded, Loop *TheLoop,
DebugLoc IVDL, bool HasUncountableExit, VFRange &Range);
/// 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_FOR_TEST static void createLoopRegions(VPlan &Plan);
/// Wrap runtime check block \p CheckBlock in a VPIRBB and \p Cond in a
/// VPValue and connect the block to \p Plan, using the VPValue as branch
@ -83,7 +83,7 @@ struct VPlanTransforms {
/// 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_FOR_TEST static bool tryToConvertVPInstructionsToVPRecipes(
VPlanPtr &Plan,
function_ref<const InductionDescriptor *(PHINode *)>
GetIntOrFpInductionDescriptor,

View File

@ -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_FOR_TEST VPValue {
friend class VPDef;
friend struct VPDoubleValueDef;
friend class VPInterleaveRecipe;

View File

@ -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,8 @@ 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_FOR_TEST bool verifyVPlanIsValid(const VPlan &Plan,
bool VerifyLate = false);
} // namespace llvm