Skip to content

Commit ffc4d87

Browse files
authored
[llvm] annotate interfaces in Passes for DLL export (#143794)
## Purpose This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `llvm/Passes` library and other pass-related headers. These annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build. ## Background This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst). The bulk of these changes were generated automatically using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool, followed formatting with `git clang-format`. The following manual adjustments were also applied after running IDS on Linux: - Remove the redundant declaration of the `initializeKCFIPass` function from llvm/include/llvm/InitializePasses.h because IDS only auto-annotates the first declaration it encounters, and the second un-annotated declaration results in an MSVC warning - Add `LLVM_ABI` to a number of private `AnalysisKey` fields in classes that extend the `AnalysisInfoMixin` template class. - Add `LLVM_ABI` to the `ChangeReporter` and `TextChangeReporter` template class definitions in llvm/include/llvm/Passes/StandardInstrumentations.h and remove the extern template instantiations. This is the only way I've found to get everything compiling warning-free when building a DLL because both template classes have methods implemented out-of-line. ## Validation Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations: - Windows with MSVC - Windows with Clang - Linux with GCC - Linux with Clang - Darwin with Clang
1 parent 4cd3e41 commit ffc4d87

File tree

9 files changed

+469
-443
lines changed

9 files changed

+469
-443
lines changed

llvm/include/llvm/InitializePasses.h

Lines changed: 301 additions & 288 deletions
Large diffs are not rendered by default.

llvm/include/llvm/Pass.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#ifdef EXPENSIVE_CHECKS
3232
#include <cstdint>
3333
#endif
34+
#include "llvm/Support/Compiler.h"
3435
#include <string>
3536

3637
namespace llvm {
@@ -95,7 +96,7 @@ const char *to_string(ThinOrFullLTOPhase Phase);
9596
/// interprocedural optimization or you do not fit into any of the more
9697
/// constrained passes described below.
9798
///
98-
class Pass {
99+
class LLVM_ABI Pass {
99100
AnalysisResolver *Resolver = nullptr; // Used to resolve analysis
100101
const void *PassID;
101102
PassKind Kind;
@@ -252,7 +253,7 @@ class Pass {
252253
/// interprocedural optimizations and analyses. ModulePasses may do anything
253254
/// they want to the program.
254255
///
255-
class ModulePass : public Pass {
256+
class LLVM_ABI ModulePass : public Pass {
256257
public:
257258
explicit ModulePass(char &pid) : Pass(PT_Module, pid) {}
258259

@@ -282,7 +283,7 @@ class ModulePass : public Pass {
282283
/// ImmutablePass class - This class is used to provide information that does
283284
/// not need to be run. This is useful for things like target information.
284285
///
285-
class ImmutablePass : public ModulePass {
286+
class LLVM_ABI ImmutablePass : public ModulePass {
286287
public:
287288
explicit ImmutablePass(char &pid) : ModulePass(pid) {}
288289

@@ -311,7 +312,7 @@ class ImmutablePass : public ModulePass {
311312
/// 2. Optimizing a function does not cause the addition or removal of any
312313
/// functions in the module
313314
///
314-
class FunctionPass : public Pass {
315+
class LLVM_ABI FunctionPass : public Pass {
315316
public:
316317
explicit FunctionPass(char &pid) : Pass(PT_Function, pid) {}
317318

@@ -338,13 +339,13 @@ class FunctionPass : public Pass {
338339
/// If the user specifies the -time-passes argument on an LLVM tool command line
339340
/// then the value of this boolean will be true, otherwise false.
340341
/// This is the storage for the -time-passes option.
341-
extern bool TimePassesIsEnabled;
342+
LLVM_ABI extern bool TimePassesIsEnabled;
342343
/// If TimePassesPerRun is true, there would be one line of report for
343344
/// each pass invocation.
344345
/// If TimePassesPerRun is false, there would be only one line of
345346
/// report for each pass (even there are more than one pass objects).
346347
/// (For new pass manager only)
347-
extern bool TimePassesPerRun;
348+
LLVM_ABI extern bool TimePassesPerRun;
348349

349350
} // end namespace llvm
350351

llvm/include/llvm/PassAnalysisSupport.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "llvm/ADT/STLExtras.h"
2626
#include "llvm/ADT/SmallVector.h"
27+
#include "llvm/Support/Compiler.h"
2728
#include <cassert>
2829
#include <tuple>
2930
#include <utility>
@@ -69,14 +70,14 @@ class AnalysisUsage {
6970

7071
///@{
7172
/// Add the specified ID to the required set of the usage info for a pass.
72-
AnalysisUsage &addRequiredID(const void *ID);
73-
AnalysisUsage &addRequiredID(char &ID);
73+
LLVM_ABI AnalysisUsage &addRequiredID(const void *ID);
74+
LLVM_ABI AnalysisUsage &addRequiredID(char &ID);
7475
template<class PassClass>
7576
AnalysisUsage &addRequired() {
7677
return addRequiredID(PassClass::ID);
7778
}
7879

79-
AnalysisUsage &addRequiredTransitiveID(char &ID);
80+
LLVM_ABI AnalysisUsage &addRequiredTransitiveID(char &ID);
8081
template<class PassClass>
8182
AnalysisUsage &addRequiredTransitive() {
8283
return addRequiredTransitiveID(PassClass::ID);
@@ -124,7 +125,7 @@ class AnalysisUsage {
124125
/// preserved by this pass. If no such Pass exists, do nothing. This can be
125126
/// useful when a pass is trivially preserved, but may not be linked in. Be
126127
/// careful about spelling!
127-
AnalysisUsage &addPreserved(StringRef Arg);
128+
LLVM_ABI AnalysisUsage &addPreserved(StringRef Arg);
128129

129130
/// Set by analyses that do not transform their input at all
130131
void setPreservesAll() { PreservesAll = true; }
@@ -139,7 +140,7 @@ class AnalysisUsage {
139140
///
140141
/// This function annotates the AnalysisUsage info object to say that analyses
141142
/// that only depend on the CFG are preserved by this pass.
142-
void setPreservesCFG();
143+
LLVM_ABI void setPreservesCFG();
143144

144145
const VectorType &getRequiredSet() const { return Required; }
145146
const VectorType &getRequiredTransitiveSet() const {
@@ -174,7 +175,8 @@ class AnalysisResolver {
174175
}
175176

176177
/// Find pass that is implementing PI. Initialize pass for Function F.
177-
std::tuple<Pass *, bool> findImplPass(Pass *P, AnalysisID PI, Function &F);
178+
LLVM_ABI std::tuple<Pass *, bool> findImplPass(Pass *P, AnalysisID PI,
179+
Function &F);
178180

179181
void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
180182
if (findImplPass(PI) == P)
@@ -189,7 +191,7 @@ class AnalysisResolver {
189191
}
190192

191193
/// Return analysis result or null if it doesn't exist.
192-
Pass *getAnalysisIfAvailable(AnalysisID ID) const;
194+
LLVM_ABI Pass *getAnalysisIfAvailable(AnalysisID ID) const;
193195

194196
private:
195197
/// This keeps track of which passes implements the interfaces that are

llvm/include/llvm/PassRegistry.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/DenseMap.h"
2020
#include "llvm/ADT/StringMap.h"
2121
#include "llvm/ADT/StringRef.h"
22+
#include "llvm/Support/Compiler.h"
2223
#include "llvm/Support/RWMutex.h"
2324
#include <memory>
2425
#include <vector>
@@ -49,36 +50,36 @@ class PassRegistry {
4950

5051
public:
5152
PassRegistry() = default;
52-
~PassRegistry();
53+
LLVM_ABI ~PassRegistry();
5354

5455
/// getPassRegistry - Access the global registry object, which is
5556
/// automatically initialized at application launch and destroyed by
5657
/// llvm_shutdown.
57-
static PassRegistry *getPassRegistry();
58+
LLVM_ABI static PassRegistry *getPassRegistry();
5859

5960
/// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'
6061
/// type identifier (&MyPass::ID).
61-
const PassInfo *getPassInfo(const void *TI) const;
62+
LLVM_ABI const PassInfo *getPassInfo(const void *TI) const;
6263

6364
/// getPassInfo - Look up a pass' corresponding PassInfo, indexed by the pass'
6465
/// argument string.
65-
const PassInfo *getPassInfo(StringRef Arg) const;
66+
LLVM_ABI const PassInfo *getPassInfo(StringRef Arg) const;
6667

6768
/// registerPass - Register a pass (by means of its PassInfo) with the
6869
/// registry. Required in order to use the pass with a PassManager.
69-
void registerPass(const PassInfo &PI, bool ShouldFree = false);
70+
LLVM_ABI void registerPass(const PassInfo &PI, bool ShouldFree = false);
7071

7172
/// enumerateWith - Enumerate the registered passes, calling the provided
7273
/// PassRegistrationListener's passEnumerate() callback on each of them.
73-
void enumerateWith(PassRegistrationListener *L);
74+
LLVM_ABI void enumerateWith(PassRegistrationListener *L);
7475

7576
/// addRegistrationListener - Register the given PassRegistrationListener
7677
/// to receive passRegistered() callbacks whenever a new pass is registered.
77-
void addRegistrationListener(PassRegistrationListener *L);
78+
LLVM_ABI void addRegistrationListener(PassRegistrationListener *L);
7879

7980
/// removeRegistrationListener - Unregister a PassRegistrationListener so that
8081
/// it no longer receives passRegistered() callbacks.
81-
void removeRegistrationListener(PassRegistrationListener *L);
82+
LLVM_ABI void removeRegistrationListener(PassRegistrationListener *L);
8283
};
8384

8485
} // end namespace llvm

llvm/include/llvm/PassSupport.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/ADT/StringRef.h"
2828
#include "llvm/PassInfo.h"
2929
#include "llvm/PassRegistry.h"
30+
#include "llvm/Support/Compiler.h"
3031
#include "llvm/Support/Error.h"
3132
#include "llvm/Support/Threading.h"
3233
#include <functional>
@@ -112,7 +113,7 @@ struct PassRegistrationListener {
112113

113114
/// enumeratePasses - Iterate over the registered passes, calling the
114115
/// passEnumerate callback on each PassInfo object.
115-
void enumeratePasses();
116+
LLVM_ABI void enumeratePasses();
116117

117118
/// passEnumerate - Callback function invoked when someone calls
118119
/// enumeratePasses on this PassRegistrationListener object.

llvm/include/llvm/Passes/OptimizationLevel.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef LLVM_PASSES_OPTIMIZATIONLEVEL_H
1616
#define LLVM_PASSES_OPTIMIZATIONLEVEL_H
1717

18+
#include "llvm/Support/Compiler.h"
1819
#include <assert.h>
1920

2021
namespace llvm {
@@ -38,7 +39,7 @@ class OptimizationLevel final {
3839
/// Disable as many optimizations as possible. This doesn't completely
3940
/// disable the optimizer in all cases, for example always_inline functions
4041
/// can be required to be inlined for correctness.
41-
static const OptimizationLevel O0;
42+
LLVM_ABI static const OptimizationLevel O0;
4243

4344
/// Optimize quickly without destroying debuggability.
4445
///
@@ -54,7 +55,7 @@ class OptimizationLevel final {
5455
/// vectorization, or fusion don't make sense here due to the degree to
5556
/// which the executed code differs from the source code, and the compile
5657
/// time cost.
57-
static const OptimizationLevel O1;
58+
LLVM_ABI static const OptimizationLevel O1;
5859
/// Optimize for fast execution as much as possible without triggering
5960
/// significant incremental compile time or code size growth.
6061
///
@@ -71,7 +72,7 @@ class OptimizationLevel final {
7172
///
7273
/// This is expected to be a good default optimization level for the vast
7374
/// majority of users.
74-
static const OptimizationLevel O2;
75+
LLVM_ABI static const OptimizationLevel O2;
7576
/// Optimize for fast execution as much as possible.
7677
///
7778
/// This mode is significantly more aggressive in trading off compile time
@@ -86,7 +87,7 @@ class OptimizationLevel final {
8687
/// order to make even significantly slower compile times at least scale
8788
/// reasonably. This does not preclude very substantial constant factor
8889
/// costs though.
89-
static const OptimizationLevel O3;
90+
LLVM_ABI static const OptimizationLevel O3;
9091
/// Similar to \c O2 but tries to optimize for small code size instead of
9192
/// fast execution without triggering significant incremental execution
9293
/// time slowdowns.
@@ -97,15 +98,15 @@ class OptimizationLevel final {
9798
/// A consequence of the different core goal is that this should in general
9899
/// produce substantially smaller executables that still run in
99100
/// a reasonable amount of time.
100-
static const OptimizationLevel Os;
101+
LLVM_ABI static const OptimizationLevel Os;
101102
/// A very specialized mode that will optimize for code size at any and all
102103
/// costs.
103104
///
104105
/// This is useful primarily when there are absolute size limitations and
105106
/// any effort taken to reduce the size is worth it regardless of the
106107
/// execution time impact. You should expect this level to produce rather
107108
/// slow, but very small, code.
108-
static const OptimizationLevel Oz;
109+
LLVM_ABI static const OptimizationLevel Oz;
109110

110111
bool isOptimizingForSpeed() const { return SizeLevel == 0 && SpeedLevel > 0; }
111112

0 commit comments

Comments
 (0)