-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[AArch64] Add AArch64PassRegistry.def #85215
Conversation
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-llvm-transforms Author: None (paperchalice) ChangesFull diff: https://github.com/llvm/llvm-project/pull/85215.diff 5 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64CodeGenPassBuilder.cpp b/llvm/lib/Target/AArch64/AArch64CodeGenPassBuilder.cpp
new file mode 100644
index 00000000000000..791cb3728c1ce3
--- /dev/null
+++ b/llvm/lib/Target/AArch64/AArch64CodeGenPassBuilder.cpp
@@ -0,0 +1,40 @@
+//===-- AArch64CodeGenPassBuilder.cpp -----------------------------*- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file contains AArch64 CodeGen pipeline builder.
+/// TODO: Port CodeGen passes to new pass manager.
+//===----------------------------------------------------------------------===//
+
+#include "AArch64LoopIdiomTransform.h"
+#include "AArch64TargetMachine.h"
+
+void AArch64TargetMachine::registerPassBuilderCallbacks(
+ PassBuilder &PB, bool PopulateClassToPassNames) {
+ if (PopulateClassToPassNames) {
+ auto *PIC = PB.getPassInstrumentationCallbacks();
+#define LOOP_PASS(NAME, CREATE_PASS) \
+ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
+#include "AArch64PassRegistry.def"
+ }
+
+ PB.registerPipelineParsingCallback(
+ [](StringRef Name, LoopPassManager &LPM, ArrayRef<PipelineElement>) {
+#define LOOP_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) { \
+ LPM.addPass(CREATE_PASS); \
+ return true; \
+ }
+#include "AArch64PassRegistry.def"
+ return false;
+ });
+
+ PB.registerLateLoopOptimizationsEPCallback(
+ [=](LoopPassManager &LPM, OptimizationLevel Level) {
+ LPM.addPass(AArch64LoopIdiomTransformPass());
+ });
+}
diff --git a/llvm/lib/Target/AArch64/AArch64PassRegistry.def b/llvm/lib/Target/AArch64/AArch64PassRegistry.def
new file mode 100644
index 00000000000000..db566d45620022
--- /dev/null
+++ b/llvm/lib/Target/AArch64/AArch64PassRegistry.def
@@ -0,0 +1,19 @@
+//===- AArch64PassRegistry.def - Registry of AArch64 passes -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is used as the registry of passes that are part of the X86 backend.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+#ifndef LOOP_PASS
+#define LOOP_PASS(NAME, CREATE_PASS)
+#endif
+LOOP_PASS("aarch64-lit", AArch64LoopIdiomTransformPass())
+#undef LOOP_PASS
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index e5e60459e8148a..f4bcf6d68b52c3 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -11,7 +11,6 @@
#include "AArch64TargetMachine.h"
#include "AArch64.h"
-#include "AArch64LoopIdiomTransform.h"
#include "AArch64MachineFunctionInfo.h"
#include "AArch64MachineScheduler.h"
#include "AArch64MacroFusion.h"
@@ -545,14 +544,6 @@ class AArch64PassConfig : public TargetPassConfig {
} // end anonymous namespace
-void AArch64TargetMachine::registerPassBuilderCallbacks(
- PassBuilder &PB, bool PopulateClassToPassNames) {
- PB.registerLateLoopOptimizationsEPCallback(
- [=](LoopPassManager &LPM, OptimizationLevel Level) {
- LPM.addPass(AArch64LoopIdiomTransformPass());
- });
-}
-
TargetTransformInfo
AArch64TargetMachine::getTargetTransformInfo(const Function &F) const {
return TargetTransformInfo(AArch64TTIImpl(this, F));
diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt
index 95b228f293204e..7aa29fce60ab1b 100644
--- a/llvm/lib/Target/AArch64/CMakeLists.txt
+++ b/llvm/lib/Target/AArch64/CMakeLists.txt
@@ -47,6 +47,7 @@ add_llvm_target(AArch64CodeGen
AArch64BranchTargets.cpp
AArch64CallingConvention.cpp
AArch64CleanupLocalDynamicTLSPass.cpp
+ AArch64CodeGenPassBuilder.cpp
AArch64CollectLOH.cpp
AArch64CondBrTuning.cpp
AArch64ConditionalCompares.cpp
diff --git a/llvm/test/Transforms/LoopIdiom/AArch64/byte-compare-index.ll b/llvm/test/Transforms/LoopIdiom/AArch64/byte-compare-index.ll
index e6a0c5f45375fd..e6d88de6314d29 100644
--- a/llvm/test/Transforms/LoopIdiom/AArch64/byte-compare-index.ll
+++ b/llvm/test/Transforms/LoopIdiom/AArch64/byte-compare-index.ll
@@ -2,6 +2,9 @@
; RUN: opt -aarch64-lit -aarch64-lit-verify -verify-dom-info -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s
; RUN: opt -aarch64-lit -simplifycfg -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s --check-prefix=LOOP-DEL
; RUN: opt -aarch64-lit -mtriple aarch64-unknown-linux-gnu -S < %s | FileCheck %s --check-prefix=NO-TRANSFORM
+; RUN: opt -p aarch64-lit -aarch64-lit-verify -verify-dom-info -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s
+; RUN: opt -p aarch64-lit -simplifycfg -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s --check-prefix=LOOP-DEL
+; RUN: opt -p aarch64-lit -mtriple aarch64-unknown-linux-gnu -S < %s | FileCheck %s --check-prefix=NO-TRANSFORM
define i32 @compare_bytes_simple(ptr %a, ptr %b, i32 %len, i32 %extra, i32 %n) {
; CHECK-LABEL: define i32 @compare_bytes_simple(
|
fe025b4
to
228002a
Compare
|
||
using namespace llvm; | ||
|
||
void AArch64TargetMachine::registerPassBuilderCallbacks( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why was this moved to a different file? it's still a method in AArch64TargetMachine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we choose to create a single header per pass, imo use a dedicated file to process them would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I sort of see what you mean, but I think it's very confusing that one method in a class is defined in a different file than the other methods. I'd be fine with forwarding the actual implementation to a different helper function that's defined in a different file, but the actual AArch64TargetMachine
method should stay in the original file
|
||
void AArch64TargetMachine::registerPassBuilderCallbacks( | ||
PassBuilder &PB, bool PopulateClassToPassNames) { | ||
if (PopulateClassToPassNames) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think it's possible to generalize this even more so each backend doesn't have to copy paste this code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about a new tablegen backend?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh man I really don't want to use tablegen for this.
I think a solution would require the preprocessor since the existing code does a lot with the preprocessor
7533bc6
to
f887646
Compare
New PM test is regenerated due to the |
f5ee6a5
to
0a98ff8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the tests re-use the same CHECK lines, and if not why are they different? Thanks
There is a loop canonicalization stage before running loop passes, it may modify CFG. llvm-project/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h Lines 438 to 448 in c0d03d2
|
3f5a2ef
to
bde44fb
Compare
#define ADD_CLASS_PASS_TO_PASS_NAME(NAME, CREATE_PASS) \ | ||
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); | ||
#define ADD_CLASS_PASS_TO_PASS_NAME_WITH_PARAMS(NAME, CLASS) \ | ||
PIC->addClassToPassName(CLASS, NAME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be
#define ADD_CLASS_PASS_TO_PASS_NAME_WITH_PARAMS(NAME, CREATE_PASS) \
{ \
std::function C_ = CREATE_PASS; \
PIC->addClassToPassName(decltype(C_)::result_type::name(), \
NAME); \
}
So MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS)
-> MODULE_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER, PARAMS)
ICE occurs when msvc compiling the following code: int main() {
constexpr bool b = std::size({"",}) > 1;
} Looks like it's been fixed in msvc v19.30. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
76846e5
to
eff29b2
Compare
Could you please add more details in the PR description? |
Done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks like the right direction to go
return true; \ | ||
} | ||
|
||
if constexpr (HAVE_MODULE_PASS_) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd keep things simple and not have the constexpr logic (meaning always add parsing callbacks) since pipeline parsing speed is not important for compile times. Unless you have a specific reason for doing so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just reduce the number of callbacks, will clear it later.
@@ -2,6 +2,9 @@ | |||
; RUN: opt -aarch64-lit -aarch64-lit-verify -verify-dom-info -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s | |||
; RUN: opt -aarch64-lit -simplifycfg -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s --check-prefix=LOOP-DEL | |||
; RUN: opt -aarch64-lit -mtriple aarch64-unknown-linux-gnu -S < %s | FileCheck %s --check-prefix=NO-TRANSFORM | |||
; RUN: opt -p aarch64-lit -aarch64-lit-verify -verify-dom-info -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s --check-prefix=CHECK-NPM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you know why the new PM pass gives different results? ideally we wouldn't be adding thousands of CHECK lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Input pipeline isfunction(loop(aarch64-lit))
, the real pipeline is loop-simplify,lcssa,loop(aarch64-lit)
The LoopSimplifiy
pass modifies the cfg here.
llvm-project/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
Lines 438 to 448 in c0d03d2
explicit FunctionToLoopPassAdaptor(std::unique_ptr<PassConceptT> Pass, | |
bool UseMemorySSA = false, | |
bool UseBlockFrequencyInfo = false, | |
bool UseBranchProbabilityInfo = false, | |
bool LoopNestMode = false) | |
: Pass(std::move(Pass)), UseMemorySSA(UseMemorySSA), | |
UseBlockFrequencyInfo(UseBlockFrequencyInfo), | |
UseBranchProbabilityInfo(UseBranchProbabilityInfo), | |
LoopNestMode(LoopNestMode) { | |
LoopCanonicalizationFPM.addPass(LoopSimplifyPass()); | |
LoopCanonicalizationFPM.addPass(LCSSAPass()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense, but can figure out how to not add thousands of CHECK lines just to make sure the new PM pass works? either create a new test, or change the test to already be in loop simplify and LCSSA form (committed in a separate change and rebase this change on that)
cd962e1
to
c7a2423
Compare
9a9992f
to
cd962e1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in general looks good, but a couple of comments
}); | ||
|
||
PB.registerParseAACallback([](StringRef Name, AAManager &AM) { | ||
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems wrong, we're registering an AA analysis for every function analysis?
I think we can just drop this part and let specific backends that have their own AA manually register them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, forgot to update it.
NVPTX and AMDGPU meed it, currently there's no harm in keeping it 🤔.
@@ -2,6 +2,9 @@ | |||
; RUN: opt -aarch64-lit -aarch64-lit-verify -verify-dom-info -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s | |||
; RUN: opt -aarch64-lit -simplifycfg -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s --check-prefix=LOOP-DEL | |||
; RUN: opt -aarch64-lit -mtriple aarch64-unknown-linux-gnu -S < %s | FileCheck %s --check-prefix=NO-TRANSFORM | |||
; RUN: opt -p aarch64-lit -aarch64-lit-verify -verify-dom-info -mtriple aarch64-unknown-linux-gnu -mattr=+sve -S < %s | FileCheck %s --check-prefix=CHECK-NPM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense, but can figure out how to not add thousands of CHECK lines just to make sure the new PM pass works? either create a new test, or change the test to already be in loop simplify and LCSSA form (committed in a separate change and rebase this change on that)
5d56740
to
234c81a
Compare
Make this test case work on both new and legacy pass manager. See also llvm#85215
234c81a
to
7bfe5b2
Compare
I'd put |
Make this test case work on both new and legacy pass manager. See also #85215
7bfe5b2
to
f86cc24
Compare
Make this test case work on both new and legacy pass manager. See also llvm#85215
PR llvm#83567 ports `SelectionDAGISel` to the new pass manager, then each backend should provide `<Target>DagToDagISel()` in new pass manager style. Then each target should provide `<Target>PassRegistry.def` to register backend passes in `registerPassBuilderCallbacks` to reduce duplicate code. This PR adds `AArch64PassRegistry.def` to AArch64 backend and boilerplate code in `registerPassBuilderCallbacks`.
PR #83567 ports
SelectionDAGISel
to the new pass manager, then each backend should provide<Target>DagToDagISel()
in new pass manager style. Then each target should provide<Target>PassRegistry.def
to register backend passes inregisterPassBuilderCallbacks
to reduce duplicate code.This PR adds
AArch64PassRegistry.def
to AArch64 backend and boilerplate code inregisterPassBuilderCallbacks
.