Skip to content

[SandboxVectorizer] Use sbvec-passes flag to create a pipeline of Region passes after BottomUpVec. #111223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Oct 9, 2024

Conversation

slackito
Copy link
Collaborator

@slackito slackito commented Oct 5, 2024

The main change is that the main SandboxVectorizer pass no longer has a pipeline of function passes. Now it consists of a BottomUpVec pass and a pipeline of region passes after it.

BottomUpVec now takes a RegionPassManager as an argument to the constructor. This argument is currently stored and not used, but the idea is that after BottomUpVec vectorizes a region of a function, we'll run successive optimization passes on that region.

I've also moved creation of the pass pipeline out of the run method to the SandboxVectorizer constructor.

…ion passes after BottomUpVec.

The main change is that the main SandboxVectorizer pass no longer has a
pipeline of function passes. Now it consists of a BottomUpVec pass and
a pipeline of region passes after it.

BottomUpVec now takes a RegionPassManager as an argument to the
constructor. This argument is currently stored and not used, but the
idea is that after BottomUpVec vectorizes a region of a function, we'll
run successive optimization passes on that region.

I've also moved creation of the pass pipeline out of the `run` method to
the SandboxVectorizer constructor.
@slackito
Copy link
Collaborator Author

slackito commented Oct 5, 2024

I'm not sure this is the way it should work but if not at least I hope to get some clarity out of the review :)

@llvmbot
Copy link
Member

llvmbot commented Oct 5, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Jorge Gorbe Moya (slackito)

Changes

The main change is that the main SandboxVectorizer pass no longer has a pipeline of function passes. Now it consists of a BottomUpVec pass and a pipeline of region passes after it.

BottomUpVec now takes a RegionPassManager as an argument to the constructor. This argument is currently stored and not used, but the idea is that after BottomUpVec vectorizes a region of a function, we'll run successive optimization passes on that region.

I've also moved creation of the pass pipeline out of the run method to the SandboxVectorizer constructor.


Full diff: https://github.com/llvm/llvm-project/pull/111223.diff

7 Files Affected:

  • (modified) llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h (+6-1)
  • (added) llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h (+19)
  • (modified) llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h (+17-2)
  • (modified) llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp (+2)
  • (modified) llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp (+57-23)
  • (modified) llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll (+1-2)
  • (modified) llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll (+4-4)
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
index a2108f07c28e50..e3a35b09d0e296 100644
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
@@ -19,14 +19,19 @@
 
 namespace llvm::sandboxir {
 
+class RegionPassManager;
+
 class BottomUpVec final : public FunctionPass {
   bool Change = false;
   LegalityAnalysis Legality;
   void vectorizeRec(ArrayRef<Value *> Bndl);
   void tryVectorize(ArrayRef<Value *> Seeds);
 
+  [[maybe_unused]] RegionPassManager *RPM;
+
 public:
-  BottomUpVec() : FunctionPass("bottom-up-vec") {}
+  BottomUpVec(RegionPassManager *RPM)
+      : FunctionPass("bottom-up-vec"), RPM(RPM) {}
   bool runOnFunction(Function &F) final;
 };
 
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h
new file mode 100644
index 00000000000000..75b9f42520156c
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h
@@ -0,0 +1,19 @@
+#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_NULLPASS_H
+#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_NULLPASS_H
+
+#include "llvm/SandboxIR/Pass.h"
+
+namespace llvm::sandboxir {
+
+class Region;
+
+/// A Region pass that does nothing, for use as a placeholder in tests.
+class NullPass final : public RegionPass {
+public:
+  NullPass() : RegionPass("null") {}
+  bool runOnRegion(Region &R) final { return false; }
+};
+
+} // namespace llvm::sandboxir
+
+#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_NULLPASS_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h
index dd9f02d3272643..4547217773cd01 100644
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h
@@ -8,7 +8,11 @@
 #ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZER_H
 #define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZER_H
 
+#include <memory>
+
 #include "llvm/IR/PassManager.h"
+#include "llvm/SandboxIR/PassManager.h"
+#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h"
 
 namespace llvm {
 
@@ -17,10 +21,21 @@ class TargetTransformInfo;
 class SandboxVectorizerPass : public PassInfoMixin<SandboxVectorizerPass> {
   TargetTransformInfo *TTI = nullptr;
 
-public:
-  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+  // Used to build a RegionPass pipeline to be run on Regions created by the
+  // bottom-up vectorization pass.
+  sandboxir::PassRegistry PR;
+
+  // The main vectorizer pass.
+  std::unique_ptr<sandboxir::BottomUpVec> BottomUpVecPass;
+
+  // The PM containing the pipeline of region passes. It's owned by the pass
+  // registry.
+  sandboxir::RegionPassManager *RPM;
 
   bool runImpl(Function &F);
+public:
+  SandboxVectorizerPass();
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
 };
 
 } // namespace llvm
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
index c59abd09d43629..69ddfaf7784eae 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
@@ -59,6 +59,8 @@ bool BottomUpVec::runOnFunction(Function &F) {
     // TODO: Replace with proper SeedCollector function.
     auto Seeds = collectSeeds(BB);
     // TODO: Slice Seeds into smaller chunks.
+    // TODO: If vectorization succeeds, run the RegionPassManager on the
+    // resulting region.
     if (Seeds.size() >= 2)
       tryVectorize(Seeds);
   }
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
index 80afcb499a2c22..1192cc5d9bb243 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
@@ -12,6 +12,7 @@
 #include "llvm/SandboxIR/PassManager.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h"
+#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h"
 
 using namespace llvm;
 
@@ -30,6 +31,57 @@ cl::opt<std::string> UserDefinedPassPipeline(
     cl::desc("Comma-separated list of vectorizer passes. If not set "
              "we run the predefined pipeline."));
 
+static void registerAllRegionPasses(sandboxir::PassRegistry &PR) {
+  PR.registerPass(std::make_unique<sandboxir::NullPass>());
+}
+
+static sandboxir::RegionPassManager &
+parseAndCreatePassPipeline(sandboxir::PassRegistry &PR, StringRef Pipeline) {
+  static constexpr const char EndToken = '\0';
+  // Add EndToken to the end to ease parsing.
+  std::string PipelineStr = std::string(Pipeline) + EndToken;
+  int FlagBeginIdx = 0;
+  auto &RPM = static_cast<sandboxir::RegionPassManager &>(
+      PR.registerPass(std::make_unique<sandboxir::RegionPassManager>("rpm")));
+
+  for (auto [Idx, C] : enumerate(PipelineStr)) {
+    // Keep moving Idx until we find the end of the pass name.
+    bool FoundDelim = C == EndToken || C == PR.PassDelimToken;
+    if (!FoundDelim)
+      continue;
+    unsigned Sz = Idx - FlagBeginIdx;
+    std::string PassName(&PipelineStr[FlagBeginIdx], Sz);
+    FlagBeginIdx = Idx + 1;
+
+    // Get the pass that corresponds to PassName and add it to the pass manager.
+    auto *Pass = PR.getPassByName(PassName);
+    if (Pass == nullptr) {
+      errs() << "Pass '" << PassName << "' not registered!\n";
+      exit(1);
+    }
+    // TODO: Add a type check here. The downcast is correct as long as
+    // registerAllRegionPasses only registers regions passes.
+    RPM.addPass(static_cast<sandboxir::RegionPass *>(Pass));
+  }
+  return RPM;
+}
+
+SandboxVectorizerPass::SandboxVectorizerPass() {
+  registerAllRegionPasses(PR);
+
+  // Create a pipeline to be run on each Region created by BottomUpVec.
+  if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
+    // Create the default pass pipeline.
+    RPM = &static_cast<sandboxir::RegionPassManager &>(PR.registerPass(
+        std::make_unique<sandboxir::FunctionPassManager>("rpm")));
+    // TODO: Add passes to the default pipeline.
+  } else {
+    // Create the user-defined pipeline.
+    RPM = &parseAndCreatePassPipeline(PR, UserDefinedPassPipeline);
+  }
+  BottomUpVecPass = std::make_unique<sandboxir::BottomUpVec>(RPM);
+}
+
 PreservedAnalyses SandboxVectorizerPass::run(Function &F,
                                              FunctionAnalysisManager &AM) {
   TTI = &AM.getResult<TargetIRAnalysis>(F);
@@ -56,31 +108,13 @@ bool SandboxVectorizerPass::runImpl(Function &LLVMF) {
     return false;
   }
 
-  sandboxir::Context Ctx(LLVMF.getContext());
-  // Create SandboxIR for `LLVMF`.
-  sandboxir::Function &F = *Ctx.createFunction(&LLVMF);
-  // Create the passes and register them with the PassRegistry.
-  sandboxir::PassRegistry PR;
-  auto &BottomUpVecPass = static_cast<sandboxir::FunctionPass &>(
-      PR.registerPass(std::make_unique<sandboxir::BottomUpVec>()));
-
-  sandboxir::FunctionPassManager *PM = nullptr;
-  if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
-    // Create the default pass pipeline.
-    PM = &static_cast<sandboxir::FunctionPassManager &>(PR.registerPass(
-        std::make_unique<sandboxir::FunctionPassManager>("pm")));
-    PM->addPass(&BottomUpVecPass);
-  } else {
-    // Create the user-defined pipeline.
-    PM = &PR.parseAndCreatePassPipeline(UserDefinedPassPipeline);
-  }
-
   if (PrintPassPipeline) {
-    PM->printPipeline(outs());
+    RPM->printPipeline(outs());
     return false;
   }
 
-  // Run the pass pipeline.
-  bool Change = PM->runOnFunction(F);
-  return Change;
+  // Create SandboxIR for LLVMF and run BottomUpVec on it.
+  sandboxir::Context Ctx(LLVMF.getContext());
+  sandboxir::Function &F = *Ctx.createFunction(&LLVMF);
+  return BottomUpVecPass->runOnFunction(F);
 }
diff --git a/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll b/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
index 5ccd64d9f487a3..86bfbee6364788 100644
--- a/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
@@ -4,8 +4,7 @@
 
 ; This checks the default pass pipeline for the sandbox vectorizer.
 define void @pipeline() {
-; CHECK: pm
-; CHECK: bottom-up-vec
+; CHECK: rpm
 ; CHECK-EMPTY:
   ret void
 }
diff --git a/llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll b/llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll
index 2879fbba1b9c00..2e6dab0aa29c74 100644
--- a/llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll
+++ b/llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll
@@ -1,12 +1,12 @@
-; RUN: opt -passes=sandbox-vectorizer -sbvec-print-pass-pipeline -sbvec-passes=bottom-up-vec,bottom-up-vec %s -disable-output | FileCheck %s
+; RUN: opt -passes=sandbox-vectorizer -sbvec-print-pass-pipeline -sbvec-passes=null,null %s -disable-output | FileCheck %s
 
 ; !!!WARNING!!! This won't get updated by update_test_checks.py !
 
 ; This checks the user defined pass pipeline.
 define void @pipeline() {
-; CHECK: pm
-; CHECK: bottom-up-vec
-; CHECK: bottom-up-vec
+; CHECK: rpm
+; CHECK: null
+; CHECK: null
 ; CHECK-EMPTY:
   ret void
 }

Copy link

github-actions bot commented Oct 5, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

sandboxir::PassRegistry PR;

// The main vectorizer pass.
std::unique_ptr<sandboxir::BottomUpVec> BottomUpVecPass;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a member variable? It's created and used only within runOnFunction() at the moment, so making it a class member implies that it used across multiple member functions of SandboxVectorizerPass. Are you planning to move it to a separate class that SandboxVectorizerPass inherits from?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we move away from cl::opt("sbvec-passes") and to proper pass parameters, we would want the LLVM pass to hold the region pass manager in the class, rather than keep it local to runImpl, because we'd specify the region pass pipeline via the constructor

but with cl::opt I don't think it really matters

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, I thought that BottomUpVecPass would own the region pass manager so it could invoke it when it creates a region

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making it a class member implies that it used across multiple member functions of SandboxVectorizerPass

Not the only reason possible to make something a member. Making it local to runImpl means constructing the BottomUpVec pass every time, which seems like a waste to me.

Also, conceptually I see the SandboxVectorizer pass as a wrapper around BottomUpVec that handles the creation of sandbox IR. I don't see anything wrong with the wrapper owning the thing it's wrapping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the only reason possible to make something a member. Making it local to runImpl means constructing the BottomUpVec pass every time, which seems like a waste to me.

Ah yes, I forgot that we were building the pass pipeline over and over again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, I thought that BottomUpVecPass would own the region pass manager so it could invoke it when it creates a region

I missed BottomUpVec also having a reference to the region pass manager


// The PM containing the pipeline of region passes. It's owned by the pass
// registry.
sandboxir::RegionPassManager *RPM;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

registerAllRegionPasses(PR);

// Create a pipeline to be run on each Region created by BottomUpVec.
if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for this stuff. Not sure why they should be in the pass constructor.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why recreate the pipeline for each function we ever run the vectorizer on, if it's defined by a command-line flag and won't change during a compiler invocation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah totally forgot that we were rebuilding it every time.

Copy link
Contributor

@aeubanks aeubanks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems fine conceptually

sandboxir::PassRegistry PR;

// The main vectorizer pass.
std::unique_ptr<sandboxir::BottomUpVec> BottomUpVecPass;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, I thought that BottomUpVecPass would own the region pass manager so it could invoke it when it creates a region

I missed BottomUpVec also having a reference to the region pass manager

// Create the user-defined pipeline.
PM = &PR.parseAndCreatePassPipeline(UserDefinedPassPipeline);
}

if (PrintPassPipeline) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, is this the only reason SandboxVectorizerPass has a reference to the region pass manager? I think ideally only the BoUpVectorizer has a reference to it, and we can call BottomUpVecPass->printPipeline(), which forwards to RPM->printPipeline()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm fine with BottomUpVec owning the region pass manager instead. I considered it and took the lazy way out because it made it easier to print the pipeline here :)

I'll change it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I'm not sure I'm completely happy with the pattern where the RegionPassManager object is actually owned by the PassRegistry, but I don't think it will cause any problems either and if we go with it we can always change it afterwards.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, all the non-owning pointers make me sus

Everything related to the pass pipeline is now in BottomUpVec.cpp,
including pipeline creation and printing and the flags to control it.

I have also changed the `BottomUpVecPass` in `SandboxVectorizer` from
a `unique_ptr` to a plain old member, as I don't think we need that
level of indirection for anything.
/// A magic string for the default pass pipeline.
const char *DefaultPipelineMagicStr = "*";

cl::opt<std::string> UserDefinedPassPipeline(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be static/anonymous namespace

// Create the user-defined pipeline.
PM = &PR.parseAndCreatePassPipeline(UserDefinedPassPipeline);
}

if (PrintPassPipeline) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, all the non-owning pointers make me sus

Also made some flag-related globals static.
@slackito
Copy link
Collaborator Author

slackito commented Oct 7, 2024

yeah, all the non-owning pointers make me sus

Got rid of the non-owning pointer. Now the region pass manager is a simple field of BottomUpVec.


/// Adds to `RPM` a sequence of passes described by `Pipeline` from the `PR`
/// pass registry.
static void parseAndCreatePassPipeline(RegionPassManager &RPM, PassRegistry &PR,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function going to be used for non RegionPasses too? If not, should it be a member function of RPM?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be a member of RPM. The moral equivalent of this function for FunctionPassManager is currently a member function of PassRegistry:

class PassRegistry {
  ...
  FunctionPassManager &parseAndCreatePassPipeline(StringRef Pipeline);
};

If we change PassRegistry::parseAndCreatePassPipeline to get the pass manager as an argument rather than creating it inside the function, I think we could easily make it generic to avoid duplicating the pipeline parsing code:

class PassRegistry {
  ...
  template <typename PassManagerType>
  void parseAndCreatePassPipeline(PassManagerType &PM, StringRef Pipeline);
};

What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(and maybe change the Create part of the parseAndCreatePassPipeline name to something that better describes the new behavior)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm then perhaps we should deprecate the PassRegistry in favor of a PassManager that owns the passes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need something to hold the mapping between names and passes so we can dynamically create pass pipelines based on the flag value. Right now the PassRegistry is that something. What are you proposing exactly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why we need a parsePassPipeline() in more than one place. Is the PassRegistry's parsePassPipeline() still being used after this patch?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the PassRegistry's parsePassPipeline() still being used after this patch?

As it is, no. That's why I proposed templatizing it so we can create pipelines of sandbox IR function passes, region passes, etc with a single parsing function. In the future, if there is more than one sandbox IR function pass, we'll probably want to create arbitrary pipelines out of them too. But I can also just delete that member function if we think we aren't going to need it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah templatizing it is fine, we can do it when needed.

But I can also just delete that member function if we think we aren't going to need it.

That's what I was thinking of. It seems that we are not going to need it.

Also if the PassRegistry's role ends up being just a mapping from name to pass class, then we could use a .def file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this?

PassManagers now own the passes they contain, and pipeline parsing is
done by a standalone function in BottomUpVec.cpp.
#define REGION_PASS(NAME, CREATE_PASS)
#endif

REGION_PASS("null", NullPass())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need some cleanup code at the end like:

#ifdef REGION_PASS
#undef REGION_PASS
#endif

to avoid getting a warning of redefining REGION_PASS if we ever decide to include the .def file more than once

Copy link
Collaborator Author

@slackito slackito Oct 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added #undef REGION_PASS. By the time we get to the end the macro is always defined, either to something useful by the user or to an empty macro above.

#define REGION_PASS(NAME, CREATE_PASS)
#endif

REGION_PASS("null", NullPass())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also why use NullPass() and not just the class name NullPass in REGION_PASS("null", NullPass()). Isn't the class name easier to work with?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just followed the pattern for the existing FUNCTION_PASS in llvm/lib/Passes/PassRegistry.def. I have no preference one way or the other.

}

/// Adds to `RPM` a sequence of region passes described by `Pipeline`.
static void parseAndCreatePassPipeline(RegionPassManager &RPM,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that it's the pass managers that own the passes it looks a bit out of place that populating them is done with a static function, because the only users of it are the pass managers.

Wdyt about moving this to the PassManager base class?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do this, then sandboxir::PassManager has to know about vectorizer-specific passes. Is this a desired outcome?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant making parseAndCreatePassPipeline a member function of PassManager such that we call:

RPM.parseAndCreatePassPipeline(UserDefinedPassPipeline);

instead of:

parseAndCreatePassPipeline(RPM, UserDefinedPassPipeline);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. But parseAndCreatePassPipeline needs to know about the existing vectorizer passes in order to instantiate them.

Do you want llvm/lib/SandboxIR/PassManager.cpp to include all the passes from llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/* ? Should we move RegionPassManager back into the vectorizer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, conceptually parsing the pass pipeline string and building passes should not be a static function in BottomUpVec.cpp because it is a pass-manager task, not a vectorization-specific task.

Oh yes, the creator function would need to have access to the passes. Hmm could we perhaps keep the creator function here in a lambda createPass(Name) and pass the lambda as an argument to the parse function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Left createPass as a static function in BottomUpVec.h instead of a lambda because the includes and defines needed for the .def file messed up indentation and I preferred to keep that ugliness contained in its own function.

I also added a new unit test, similar to the now deleted PassRegistry test, that checks the pipeline parsing function (we also have some very basic coverage from lit tests)

The new method receives a CreatePass function as an argument to avoid
the PassManager class having to "know" about existing passes in, for
example, SandboxVectorizer.

Also added back a unit test similar to the now deleted PassRegistry test
that checks PassManager::setPassPipeline.
FPM.runOnFunction(*F);
EXPECT_EQ(Str, "foobarfoo");

// Check that a second call to setPassPipeline clears the previous pipeline.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we allow a second call to setPassPipeline() ? Shouldn't we crash if we try to do so instead?

Copy link
Contributor

@vporpo vporpo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM apart from the multiple invocations to setPassPipeline.

@slackito slackito merged commit 10ada4a into llvm:main Oct 9, 2024
6 of 8 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 9, 2024

LLVM Buildbot has detected a new failure on builder flang-aarch64-libcxx running on linaro-flang-aarch64-libcxx while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/89/builds/8127

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
79.454 [280/3/6941] Linking CXX executable bin/clang-check
83.640 [280/2/6942] Linking CXX shared library lib/libFortranSemantics.so.20.0git
83.649 [279/2/6943] Creating library symlink lib/libFortranSemantics.so
83.844 [274/6/6944] Linking CXX executable tools/flang/unittests/Evaluate/real.test
83.850 [274/5/6945] Linking CXX executable tools/flang/unittests/Evaluate/logical.test
83.856 [274/4/6946] Linking CXX executable tools/flang/unittests/Evaluate/integer.test
83.989 [274/3/6947] Linking CXX executable tools/flang/unittests/Evaluate/folding.test
84.051 [274/2/6948] Linking CXX executable tools/flang/unittests/Evaluate/expression.test
92.789 [274/1/6949] Building CXX object lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o
93.209 [273/1/6950] Linking CXX shared library lib/libLLVMPasses.so.20.0git
FAILED: lib/libLLVMPasses.so.20.0git 
: && /usr/local/bin/c++ -fPIC -stdlib=libc++ -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -stdlib=libc++ -Wl,-z,defs -Wl,-z,nodelete   -Wl,-rpath-link,/home/tcwg-buildbot/worker/flang-aarch64-libcxx/build/./lib  -Wl,--gc-sections -shared -Wl,-soname,libLLVMPasses.so.20.0git -o lib/libLLVMPasses.so.20.0git lib/Passes/CMakeFiles/LLVMPasses.dir/CodeGenPassBuilder.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/OptimizationLevel.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilderBindings.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilderPipelines.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassPlugin.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/StandardInstrumentations.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:/home/tcwg-buildbot/worker/flang-aarch64-libcxx/build/lib:"  lib/libLLVMCFGuard.so.20.0git  lib/libLLVMCodeGen.so.20.0git  lib/libLLVMCoroutines.so.20.0git  lib/libLLVMHipStdPar.so.20.0git  lib/libLLVMipo.so.20.0git  lib/libLLVMIRPrinter.so.20.0git  lib/libLLVMObjCARCOpts.so.20.0git  lib/libLLVMTarget.so.20.0git  lib/libLLVMVectorize.so.20.0git  lib/libLLVMInstrumentation.so.20.0git  lib/libLLVMScalarOpts.so.20.0git  lib/libLLVMAggressiveInstCombine.so.20.0git  lib/libLLVMInstCombine.so.20.0git  lib/libLLVMTransformUtils.so.20.0git  lib/libLLVMAnalysis.so.20.0git  lib/libLLVMCore.so.20.0git  lib/libLLVMSupport.so.20.0git  -Wl,-rpath-link,/home/tcwg-buildbot/worker/flang-aarch64-libcxx/build/lib && :
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o: in function `llvm::ModuleToFunctionPassAdaptor llvm::createModuleToFunctionPassAdaptor<llvm::SandboxVectorizerPass>(llvm::SandboxVectorizerPass&&, bool)':
PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x38): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x44): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0xa0): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0xa4): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x114): undefined reference to `vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x11c): undefined reference to `vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x13c): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x140): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x180): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x184): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x24c): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:(.text._ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b[_ZN4llvm33createModuleToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_27ModuleToFunctionPassAdaptorEOT_b]+0x254): more undefined references to `vtable for llvm::sandboxir::Pass' follow
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o: in function `llvm::CGSCCToFunctionPassAdaptor llvm::createCGSCCToFunctionPassAdaptor<llvm::SandboxVectorizerPass>(llvm::SandboxVectorizerPass&&, bool, bool)':
PassBuilder.cpp:(.text._ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb[_ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb]+0x11c): undefined reference to `vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb[_ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb]+0x124): undefined reference to `vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb[_ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb]+0x144): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb[_ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb]+0x148): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb[_ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb]+0x188): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb[_ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb]+0x18c): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb[_ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb]+0x260): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:(.text._ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb[_ZN4llvm32createCGSCCToFunctionPassAdaptorINS_21SandboxVectorizerPassEEENS_26CGSCCToFunctionPassAdaptorEOT_bb]+0x268): more undefined references to `vtable for llvm::sandboxir::Pass' follow
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o: in function `llvm::SandboxVectorizerPass::SandboxVectorizerPass(llvm::SandboxVectorizerPass&&)':
PassBuilder.cpp:(.text._ZN4llvm21SandboxVectorizerPassC2EOS0_[_ZN4llvm21SandboxVectorizerPassC2EOS0_]+0xdc): undefined reference to `vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm21SandboxVectorizerPassC2EOS0_[_ZN4llvm21SandboxVectorizerPassC2EOS0_]+0xe0): undefined reference to `vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o: in function `llvm::detail::PassModel<llvm::Function, llvm::SandboxVectorizerPass, llvm::AnalysisManager<llvm::Function>>::PassModel(llvm::SandboxVectorizerPass)':
PassBuilder.cpp:(.text._ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEEC2ES3_[_ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEEC2ES3_]+0x14): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEEC2ES3_[_ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEEC2ES3_]+0x20): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEEC2ES3_[_ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEEC2ES3_]+0xec): undefined reference to `vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEEC2ES3_[_ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEEC2ES3_]+0xf0): undefined reference to `vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o: in function `llvm::detail::PassModel<llvm::Function, llvm::SandboxVectorizerPass, llvm::AnalysisManager<llvm::Function>>::~PassModel()':
PassBuilder.cpp:(.text._ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEED2Ev[_ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEED2Ev]+0x84): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEED2Ev[_ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEED2Ev]+0x88): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o: in function `llvm::detail::PassModel<llvm::Function, llvm::SandboxVectorizerPass, llvm::AnalysisManager<llvm::Function>>::~PassModel()':
PassBuilder.cpp:(.text._ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEED0Ev[_ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEED0Ev]+0x84): undefined reference to `vtable for llvm::sandboxir::Pass'
/usr/bin/ld: PassBuilder.cpp:(.text._ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEED0Ev[_ZN4llvm6detail9PassModelINS_8FunctionENS_21SandboxVectorizerPassENS_15AnalysisManagerIS2_JEEEJEED0Ev]+0x88): undefined reference to `vtable for llvm::sandboxir::Pass'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

slackito added a commit that referenced this pull request Oct 9, 2024
…e of Region passes after BottomUpVec." (#111727)

Reverts #111223

It broke one of the build bots:

LLVM Buildbot has detected a new failure on builder flang-aarch64-libcxx
running on linaro-flang-aarch64-libcxx while building llvm at step 5
"build-unified-tree".

Full details are available at:
https://lab.llvm.org/buildbot/#/builders/89/builds/8127
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 9, 2024

LLVM Buildbot has detected a new failure on builder llvm-nvptx64-nvidia-ubuntu running on as-builder-7 while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/160/builds/6516

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
56.839 [32/7/2636] Linking CXX executable bin/llvm-libtool-darwin
56.847 [32/6/2637] Linking CXX executable bin/llvm-split
56.851 [32/5/2638] Linking CXX executable bin/llvm-dwarfutil
56.859 [32/4/2639] Linking CXX executable bin/dsymutil
56.860 [32/3/2640] Linking CXX executable bin/llvm-isel-fuzzer
56.875 [32/2/2641] Linking CXX executable bin/bugpoint
56.903 [31/2/2642] Building CXX object tools/bugpoint-passes/CMakeFiles/BugpointPasses.dir/TestPasses.cpp.o
56.963 [30/2/2643] Linking CXX shared module lib/BugpointPasses.so
84.444 [30/1/2644] Building CXX object lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o
84.773 [29/1/2645] Linking CXX shared library lib/libLLVMPasses.so.20.0git
FAILED: lib/libLLVMPasses.so.20.0git 
: && /usr/bin/c++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -fno-lifetime-dse -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete -fuse-ld=gold   -Wl,--gc-sections -shared -Wl,-soname,libLLVMPasses.so.20.0git -o lib/libLLVMPasses.so.20.0git lib/Passes/CMakeFiles/LLVMPasses.dir/CodeGenPassBuilder.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/OptimizationLevel.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilderBindings.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilderPipelines.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassPlugin.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/StandardInstrumentations.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/lib:"  lib/libLLVMCFGuard.so.20.0git  lib/libLLVMCodeGen.so.20.0git  lib/libLLVMCoroutines.so.20.0git  lib/libLLVMHipStdPar.so.20.0git  lib/libLLVMipo.so.20.0git  lib/libLLVMIRPrinter.so.20.0git  lib/libLLVMObjCARCOpts.so.20.0git  lib/libLLVMTarget.so.20.0git  lib/libLLVMVectorize.so.20.0git  lib/libLLVMInstrumentation.so.20.0git  lib/libLLVMScalarOpts.so.20.0git  lib/libLLVMAggressiveInstCombine.so.20.0git  lib/libLLVMInstCombine.so.20.0git  lib/libLLVMTransformUtils.so.20.0git  lib/libLLVMAnalysis.so.20.0git  lib/libLLVMCore.so.20.0git  lib/libLLVMSupport.so.20.0git  -Wl,-rpath-link,/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx64-nvidia-ubuntu/build/lib && :
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::detail::PassModel<llvm::Function, llvm::SandboxVectorizerPass, llvm::AnalysisManager<llvm::Function>>::~PassModel(): error: undefined reference to 'vtable for llvm::sandboxir::Pass'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::detail::PassModel<llvm::Function, llvm::SandboxVectorizerPass, llvm::AnalysisManager<llvm::Function>>::~PassModel(): error: undefined reference to 'vtable for llvm::sandboxir::Pass'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::sandboxir::BottomUpVec::BottomUpVec(llvm::sandboxir::BottomUpVec&&): error: undefined reference to 'vtable for llvm::sandboxir::Pass'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::sandboxir::BottomUpVec::BottomUpVec(llvm::sandboxir::BottomUpVec&&): error: undefined reference to 'vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::ModuleToFunctionPassAdaptor llvm::createModuleToFunctionPassAdaptor<llvm::SandboxVectorizerPass>(llvm::SandboxVectorizerPass&&, bool): error: undefined reference to 'vtable for llvm::sandboxir::Pass'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 9, 2024

LLVM Buildbot has detected a new failure on builder llvm-nvptx-nvidia-ubuntu running on as-builder-7 while building llvm at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/180/builds/6514

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
50.192 [32/7/2636] Linking CXX executable bin/llvm-libtool-darwin
50.200 [32/6/2637] Linking CXX executable bin/llvm-split
50.203 [32/5/2638] Linking CXX executable bin/llvm-dwarfutil
50.210 [32/4/2639] Linking CXX executable bin/dsymutil
50.211 [32/3/2640] Linking CXX executable bin/llvm-isel-fuzzer
50.227 [32/2/2641] Linking CXX executable bin/bugpoint
50.256 [31/2/2642] Building CXX object tools/bugpoint-passes/CMakeFiles/BugpointPasses.dir/TestPasses.cpp.o
50.316 [30/2/2643] Linking CXX shared module lib/BugpointPasses.so
94.045 [30/1/2644] Building CXX object lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o
94.381 [29/1/2645] Linking CXX shared library lib/libLLVMPasses.so.20.0git
FAILED: lib/libLLVMPasses.so.20.0git 
: && /usr/bin/c++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -fno-lifetime-dse -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete -fuse-ld=gold   -Wl,--gc-sections -shared -Wl,-soname,libLLVMPasses.so.20.0git -o lib/libLLVMPasses.so.20.0git lib/Passes/CMakeFiles/LLVMPasses.dir/CodeGenPassBuilder.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/OptimizationLevel.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilderBindings.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilderPipelines.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassPlugin.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/StandardInstrumentations.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/lib:"  lib/libLLVMCFGuard.so.20.0git  lib/libLLVMCodeGen.so.20.0git  lib/libLLVMCoroutines.so.20.0git  lib/libLLVMHipStdPar.so.20.0git  lib/libLLVMipo.so.20.0git  lib/libLLVMIRPrinter.so.20.0git  lib/libLLVMObjCARCOpts.so.20.0git  lib/libLLVMTarget.so.20.0git  lib/libLLVMVectorize.so.20.0git  lib/libLLVMInstrumentation.so.20.0git  lib/libLLVMScalarOpts.so.20.0git  lib/libLLVMAggressiveInstCombine.so.20.0git  lib/libLLVMInstCombine.so.20.0git  lib/libLLVMTransformUtils.so.20.0git  lib/libLLVMAnalysis.so.20.0git  lib/libLLVMCore.so.20.0git  lib/libLLVMSupport.so.20.0git  -Wl,-rpath-link,/home/buildbot/worker/as-builder-7/ramdisk/llvm-nvptx-nvidia-ubuntu/build/lib && :
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::detail::PassModel<llvm::Function, llvm::SandboxVectorizerPass, llvm::AnalysisManager<llvm::Function>>::~PassModel(): error: undefined reference to 'vtable for llvm::sandboxir::Pass'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::detail::PassModel<llvm::Function, llvm::SandboxVectorizerPass, llvm::AnalysisManager<llvm::Function>>::~PassModel(): error: undefined reference to 'vtable for llvm::sandboxir::Pass'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::sandboxir::BottomUpVec::BottomUpVec(llvm::sandboxir::BottomUpVec&&): error: undefined reference to 'vtable for llvm::sandboxir::Pass'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::sandboxir::BottomUpVec::BottomUpVec(llvm::sandboxir::BottomUpVec&&): error: undefined reference to 'vtable for llvm::sandboxir::RegionPassManager'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o:PassBuilder.cpp:function llvm::ModuleToFunctionPassAdaptor llvm::createModuleToFunctionPassAdaptor<llvm::SandboxVectorizerPass>(llvm::SandboxVectorizerPass&&, bool): error: undefined reference to 'vtable for llvm::sandboxir::Pass'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

slackito added a commit that referenced this pull request Oct 10, 2024
…egion passes after BottomUpVec. (#111223)" (#111772)

#111223 was reverted because of
a build failure with `-DBUILD_SHARED_LIBS=on`.

The Passes component depends on Vectorizer (because PassBuilder needs to
be able to instantiate SandboxVectorizerPass). This resulted in CMake
doing this

1. when it builds lib/libLLVMVectorize.so.20.0git it adds
lib/libLLVMSandboxIR.so.20.0git to the command line, because it's listed
as a dependency (as expected)
2. when it's trying to build lib/libLLVMPasses.so.20.0git it adds
lib/libLLVMVectorize.so.20.0git to the command line, because it's listed
as a dependency (also as expected). But not libLLVMSandboxIR.so.

When SandboxVectorizerPass has its ctors/dtors defined inline, this
caused "undefined reference to vtable" linker errors. This change works
around that by moving ctors/dtors out of line.

Also fix a bazel build problem by adding the new
`llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def`
as a textual header in the Vectorizer target.
DanielCChen pushed a commit to DanielCChen/llvm-project that referenced this pull request Oct 16, 2024
…egion passes after BottomUpVec. (llvm#111223)" (llvm#111772)

llvm#111223 was reverted because of
a build failure with `-DBUILD_SHARED_LIBS=on`.

The Passes component depends on Vectorizer (because PassBuilder needs to
be able to instantiate SandboxVectorizerPass). This resulted in CMake
doing this

1. when it builds lib/libLLVMVectorize.so.20.0git it adds
lib/libLLVMSandboxIR.so.20.0git to the command line, because it's listed
as a dependency (as expected)
2. when it's trying to build lib/libLLVMPasses.so.20.0git it adds
lib/libLLVMVectorize.so.20.0git to the command line, because it's listed
as a dependency (also as expected). But not libLLVMSandboxIR.so.

When SandboxVectorizerPass has its ctors/dtors defined inline, this
caused "undefined reference to vtable" linker errors. This change works
around that by moving ctors/dtors out of line.

Also fix a bazel build problem by adding the new
`llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def`
as a textual header in the Vectorizer target.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants