-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[WebAssembly] Implement GlobalISel #157161
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
base: main
Are you sure you want to change the base?
Conversation
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
If you want to keep tabs on it, or have any suggestions. Probably going to a little while before there's anything worth seriously reviewing. |
f144903 to
332f108
Compare
|
I'm getting close to having a MVP for you to review. But in the meanwhile, I have a question (if you don't know, maybe you'll at least know who does). I'm working on the instruction selection phase currently. The compatibility layer works pretty well for importing the existing (SelectionDAG) tblgen patterns to work with GISel. So far one of the biggest issues is that my p0 (LLT; pointers in address space 0) aren't getting matched existing patterns expecting an i32/i64 (LLT s32 or s64?). For instance, G_CONSTANT matches to CONST_I32/CONST_I64 when giving a constant s32 or s64, but fails when providing a p0 (e.g. 0 to represent null pointer). What's the best way to fix this. Do I just have to manually implement Note that regbankselect is already putting them in i32regbank or i64regbank as appropriate, so that's working. Its just isel that isn't matching them. |
|
Yeah, unfortunately I don't know that much about GIsel specifically. This sounds like a good question to bring up on Discourse. |
|
@topperc you might find this interesting. |
|
@dschuff It's obviously not fully complete, but I think its far along enough to warrant a review (does that mean I should un-draft it?). I'm not entirely sure what LLVM's policy is on PR size/completeness, but I get the strong impression the GlobalISel implementation doesn't need to be 100% the first go. Feature wise, here's a list of major things still missing (to my recollection)
Besides those, there are other things that still need adding.
Which of these do you want done before a review, and which do you think should be complete for merging this initial PR. My main focus was to get this in a functional state as quickly as possible, so there's undoubtedly plenty of room for cleanup. Call lowering in particular needs addressing, as I had to copy & paste private code from elsewhere rather than use the higher-level public API, due to WASM's unique value-stack [no phys reg, no stack spilling]. This is also basically my first time working with significantly with the LLVM codebase (short of that one small PR and issue last month), so I'm learning along the way. There seem to be lots of ways to accomplish certain tasks, so it sometimes gets confusing what the correct/optimal approach is. I suppose this is a good a time as any to ask, is there still interest in all of this? How far along does this need to get before others will start working with and improving it? |
53bd43b to
cb51d03
Compare
…lArguments and CallLowering::lowerReturn
…UNC instead of integer ANYEXT/TRUNC)
43cbdf2 to
42f62ef
Compare
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions cpp,h -- llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.h llvm/lib/Target/WebAssembly/GISel/WebAssemblyInstructionSelector.cpp llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.cpp llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h llvm/lib/Target/WebAssembly/GISel/WebAssemblyO0PreLegalizerCombiner.cpp llvm/lib/Target/WebAssembly/GISel/WebAssemblyPostLegalizerCombiner.cpp llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.cpp llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.h llvm/lib/Target/WebAssembly/WebAssembly.h llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp
index 5800d4b7f..d78fbf309 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyCallLowering.cpp
@@ -523,7 +523,7 @@ bool WebAssemblyCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
for (unsigned Part = 0; Part < NumParts; ++Part) {
auto NewOutReg = MRI.createGenericVirtualRegister(NewLLT);
assert(RBI.constrainGenericRegister(NewOutReg, NewRegClass, MRI) &&
- "Couldn't constrain brand-new register?");
+ "Couldn't constrain brand-new register?");
MIRBuilder.buildCopy(NewOutReg, Arg.Regs[Part]);
MIB.addUse(NewOutReg);
}
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h
index 5aca23c95..5e9c079f6 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyLegalizerInfo.h
@@ -25,7 +25,8 @@ class WebAssemblyLegalizerInfo : public LegalizerInfo {
public:
WebAssemblyLegalizerInfo(const WebAssemblySubtarget &ST);
- bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const override;
+ bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
+ LostDebugLocObserver &LocObserver) const override;
};
} // namespace llvm
#endif
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyO0PreLegalizerCombiner.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyO0PreLegalizerCombiner.cpp
index 521aa2535..745b3d3de 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyO0PreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyO0PreLegalizerCombiner.cpp
@@ -100,7 +100,8 @@ private:
};
} // end anonymous namespace
-void WebAssemblyO0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+void WebAssemblyO0PreLegalizerCombiner::getAnalysisUsage(
+ AnalysisUsage &AU) const {
AU.addRequired<TargetPassConfig>();
AU.setPreservesCFG();
getSelectionDAGFallbackAnalysisUsage(AU);
@@ -115,7 +116,8 @@ WebAssemblyO0PreLegalizerCombiner::WebAssemblyO0PreLegalizerCombiner()
report_fatal_error("Invalid rule identifier");
}
-bool WebAssemblyO0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
+bool WebAssemblyO0PreLegalizerCombiner::runOnMachineFunction(
+ MachineFunction &MF) {
if (MF.getProperties().hasFailedISel())
return false;
auto &TPC = getAnalysis<TargetPassConfig>();
@@ -134,7 +136,8 @@ bool WebAssemblyO0PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF
CInfo.MaxIterations = 1;
WebAssemblyO0PreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *VT,
- /*CSEInfo*/ nullptr, RuleConfig, ST);
+ /*CSEInfo*/ nullptr, RuleConfig,
+ ST);
return Impl.combineMachineInstrs();
}
@@ -146,8 +149,8 @@ INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_END(WebAssemblyO0PreLegalizerCombiner, DEBUG_TYPE,
- "Combine WebAssembly machine instrs before legalization", false,
- false)
+ "Combine WebAssembly machine instrs before legalization",
+ false, false)
FunctionPass *llvm::createWebAssemblyO0PreLegalizerCombiner() {
return new WebAssemblyO0PreLegalizerCombiner();
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPostLegalizerCombiner.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPostLegalizerCombiner.cpp
index 4bf687fc4..3f12a64ca 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPostLegalizerCombiner.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPostLegalizerCombiner.cpp
@@ -1,4 +1,5 @@
-//=== WebAssemblyPostLegalizerCombiner.cpp --------------------------*- C++ -*-===//
+//=== WebAssemblyPostLegalizerCombiner.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.
@@ -104,7 +105,8 @@ private:
};
} // end anonymous namespace
-void WebAssemblyPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+void WebAssemblyPostLegalizerCombiner::getAnalysisUsage(
+ AnalysisUsage &AU) const {
AU.addRequired<TargetPassConfig>();
AU.setPreservesCFG();
getSelectionDAGFallbackAnalysisUsage(AU);
@@ -123,7 +125,8 @@ WebAssemblyPostLegalizerCombiner::WebAssemblyPostLegalizerCombiner()
report_fatal_error("Invalid rule identifier");
}
-bool WebAssemblyPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
+bool WebAssemblyPostLegalizerCombiner::runOnMachineFunction(
+ MachineFunction &MF) {
if (MF.getProperties().hasFailedISel())
return false;
assert(MF.getProperties().hasLegalized() && "Expected a legalized function?");
@@ -146,20 +149,20 @@ bool WebAssemblyPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF)
CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
/*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
F.hasMinSize());
- WebAssemblyPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *VT, CSEInfo, RuleConfig,
- ST, MDT, LI);
+ WebAssemblyPostLegalizerCombinerImpl Impl(MF, CInfo, TPC, *VT, CSEInfo,
+ RuleConfig, ST, MDT, LI);
return Impl.combineMachineInstrs();
}
char WebAssemblyPostLegalizerCombiner::ID = 0;
INITIALIZE_PASS_BEGIN(WebAssemblyPostLegalizerCombiner, DEBUG_TYPE,
- "Combine WebAssembly MachineInstrs after legalization", false,
- false)
+ "Combine WebAssembly MachineInstrs after legalization",
+ false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
INITIALIZE_PASS_END(WebAssemblyPostLegalizerCombiner, DEBUG_TYPE,
- "Combine WebAssembly MachineInstrs after legalization", false,
- false)
+ "Combine WebAssembly MachineInstrs after legalization",
+ false, false)
FunctionPass *llvm::createWebAssemblyPostLegalizerCombiner() {
return new WebAssemblyPostLegalizerCombiner();
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp
index a939eafd7..68dfbaae5 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyPreLegalizerCombiner.cpp
@@ -1,4 +1,5 @@
-//=== WebAssemblyPreLegalizerCombiner.cpp ---------------------------------------===//
+//=== WebAssemblyPreLegalizerCombiner.cpp
+//---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -92,7 +93,9 @@ public:
WebAssemblyPreLegalizerCombiner();
- StringRef getPassName() const override { return "WebAssemblyPreLegalizerCombiner"; }
+ StringRef getPassName() const override {
+ return "WebAssemblyPreLegalizerCombiner";
+ }
bool runOnMachineFunction(MachineFunction &MF) override;
@@ -103,7 +106,8 @@ private:
};
} // end anonymous namespace
-void WebAssemblyPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
+void WebAssemblyPreLegalizerCombiner::getAnalysisUsage(
+ AnalysisUsage &AU) const {
AU.addRequired<TargetPassConfig>();
AU.setPreservesCFG();
getSelectionDAGFallbackAnalysisUsage(AU);
@@ -122,7 +126,8 @@ WebAssemblyPreLegalizerCombiner::WebAssemblyPreLegalizerCombiner()
report_fatal_error("Invalid rule identifier");
}
-bool WebAssemblyPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
+bool WebAssemblyPreLegalizerCombiner::runOnMachineFunction(
+ MachineFunction &MF) {
if (MF.getProperties().hasFailedISel())
return false;
auto &TPC = getAnalysis<TargetPassConfig>();
@@ -151,21 +156,21 @@ bool WebAssemblyPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF)
// This is the first Combiner, so the input IR might contain dead
// instructions.
CInfo.EnableFullDCE = true;
- WebAssemblyPreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *VT, CSEInfo, RuleConfig,
- ST, MDT, LI);
+ WebAssemblyPreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *VT, CSEInfo,
+ RuleConfig, ST, MDT, LI);
return Impl.combineMachineInstrs();
}
char WebAssemblyPreLegalizerCombiner::ID = 0;
INITIALIZE_PASS_BEGIN(WebAssemblyPreLegalizerCombiner, DEBUG_TYPE,
- "Combine WebAssembly machine instrs before legalization", false,
- false)
+ "Combine WebAssembly machine instrs before legalization",
+ false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_END(WebAssemblyPreLegalizerCombiner, DEBUG_TYPE,
- "Combine WebAssembly machine instrs before legalization", false,
- false)
+ "Combine WebAssembly machine instrs before legalization",
+ false, false)
FunctionPass *llvm::createWebAssemblyPreLegalizerCombiner() {
return new WebAssemblyPreLegalizerCombiner();
diff --git a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.h b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.h
index d2cde32cf..a48762e41 100644
--- a/llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.h
+++ b/llvm/lib/Target/WebAssembly/GISel/WebAssemblyRegisterBankInfo.h
@@ -58,11 +58,13 @@ public:
/// \returns true if \p MI only defines FPRs.
bool onlyDefinesFP(const MachineInstr &MI, const MachineRegisterInfo &MRI,
- const WebAssemblyRegisterInfo &TRI, unsigned Depth = 0) const;
+ const WebAssemblyRegisterInfo &TRI,
+ unsigned Depth = 0) const;
/// \returns true if \p MI can take both fpr and gpr uses, but prefers fp.
bool prefersFPUse(const MachineInstr &MI, const MachineRegisterInfo &MRI,
- const WebAssemblyRegisterInfo &TRI, unsigned Depth = 0) const;
+ const WebAssemblyRegisterInfo &TRI,
+ unsigned Depth = 0) const;
};
} // end namespace llvm
#endif
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
index 315cbb653..641eef730 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
@@ -12,12 +12,12 @@
///
//===----------------------------------------------------------------------===//
-#include "WebAssembly.h"
#include "WebAssemblySubtarget.h"
#include "GISel/WebAssemblyCallLowering.h"
#include "GISel/WebAssemblyLegalizerInfo.h"
#include "GISel/WebAssemblyRegisterBankInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
+#include "WebAssembly.h"
#include "WebAssemblyInstrInfo.h"
#include "WebAssemblyTargetMachine.h"
#include "llvm/MC/TargetRegistry.h"
@@ -78,7 +78,7 @@ WebAssemblySubtarget::WebAssemblySubtarget(const Triple &TT,
RegBankInfo.reset(RBI);
InstSelector.reset(createWebAssemblyInstructionSelector(
- *static_cast<const WebAssemblyTargetMachine *>(&TM), *this, *RBI));
+ *static_cast<const WebAssemblyTargetMachine *>(&TM), *this, *RBI));
}
bool WebAssemblySubtarget::enableAtomicExpand() const {
|
A WIP attempt to implement the new GlobalISel system for the WebAssembly backend.
It may not end up being worth the effort in the short term, but hopefully if it works out, it will open the doors to improved code maintainability and future GlobalISel-exclusive optimizations.
Based largely on the AArch GlobalISel, combined with the old SelectionDAG-based (WASM) code.