summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/Legalizer.cpp')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/Legalizer.cpp54
1 files changed, 44 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
index 8f8280a21da..84131e59948 100644
--- a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
@@ -16,6 +16,8 @@
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
+#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
#include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
@@ -33,11 +35,17 @@
using namespace llvm;
+static cl::opt<bool>
+ EnableCSEInLegalizer("enable-cse-in-legalizer",
+ cl::desc("Should enable CSE in Legalizer"),
+ cl::Optional, cl::init(false));
+
char Legalizer::ID = 0;
INITIALIZE_PASS_BEGIN(Legalizer, DEBUG_TYPE,
"Legalize the Machine IR a function's Machine IR", false,
false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
+INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
"Legalize the Machine IR a function's Machine IR", false,
false)
@@ -48,6 +56,8 @@ Legalizer::Legalizer() : MachineFunctionPass(ID) {
void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetPassConfig>();
+ AU.addRequired<GISelCSEAnalysisWrapperPass>();
+ AU.addPreserved<GISelCSEAnalysisWrapperPass>();
getSelectionDAGFallbackAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -82,7 +92,7 @@ public:
LegalizerWorkListManager(InstListTy &Insts, ArtifactListTy &Arts)
: InstList(Insts), ArtifactList(Arts) {}
- void createdInstr(const MachineInstr &MI) override {
+ void createdInstr(MachineInstr &MI) override {
// Only legalize pre-isel generic instructions.
// Legalization process could generate Target specific pseudo
// instructions with generic types. Don't record them
@@ -95,17 +105,17 @@ public:
LLVM_DEBUG(dbgs() << ".. .. New MI: " << MI);
}
- void erasingInstr(const MachineInstr &MI) override {
+ void erasingInstr(MachineInstr &MI) override {
LLVM_DEBUG(dbgs() << ".. .. Erasing: " << MI);
InstList.remove(&MI);
ArtifactList.remove(&MI);
}
- void changingInstr(const MachineInstr &MI) override {
+ void changingInstr(MachineInstr &MI) override {
LLVM_DEBUG(dbgs() << ".. .. Changing MI: " << MI);
}
- void changedInstr(const MachineInstr &MI) override {
+ void changedInstr(MachineInstr &MI) override {
// When insts change, we want to revisit them to legalize them again.
// We'll consider them the same as created.
LLVM_DEBUG(dbgs() << ".. .. Changed MI: " << MI);
@@ -122,14 +132,16 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
init(MF);
const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
+ GISelCSEAnalysisWrapper &Wrapper =
+ getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
const size_t NumBlocks = MF.size();
MachineRegisterInfo &MRI = MF.getRegInfo();
// Populate Insts
- InstListTy InstList(&MF);
- ArtifactListTy ArtifactList(&MF);
+ InstListTy InstList;
+ ArtifactListTy ArtifactList;
ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
// Perform legalization bottom up so we can DCE as we legalize.
// Traverse BB in RPOT and within each basic block, add insts top down,
@@ -148,12 +160,34 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
InstList.insert(&MI);
}
}
+ std::unique_ptr<MachineIRBuilder> MIRBuilder;
+ GISelCSEInfo *CSEInfo = nullptr;
+ bool IsO0 = TPC.getOptLevel() == CodeGenOpt::Level::None;
+ // Disable CSE for O0.
+ bool EnableCSE = !IsO0 && EnableCSEInLegalizer;
+ if (EnableCSE) {
+ MIRBuilder = make_unique<CSEMIRBuilder>();
+ std::unique_ptr<CSEConfig> Config = make_unique<CSEConfig>();
+ CSEInfo = &Wrapper.get(std::move(Config));
+ MIRBuilder->setCSEInfo(CSEInfo);
+ } else
+ MIRBuilder = make_unique<MachineIRBuilder>();
+ // This observer keeps the worklist updated.
LegalizerWorkListManager WorkListObserver(InstList, ArtifactList);
- LegalizerHelper Helper(MF, WorkListObserver);
+ // We want both WorkListObserver as well as CSEInfo to observe all changes.
+ // Use the wrapper observer.
+ GISelObserverWrapper WrapperObserver(&WorkListObserver);
+ if (EnableCSE && CSEInfo)
+ WrapperObserver.addObserver(CSEInfo);
+ // Now install the observer as the delegate to MF.
+ // This will keep all the observers notified about new insertions/deletions.
+ RAIIDelegateInstaller DelInstall(MF, &WrapperObserver);
+ LegalizerHelper Helper(MF, WrapperObserver, *MIRBuilder.get());
const LegalizerInfo &LInfo(Helper.getLegalizerInfo());
- LegalizationArtifactCombiner ArtCombiner(Helper.MIRBuilder, MF.getRegInfo(), LInfo);
- auto RemoveDeadInstFromLists = [&WorkListObserver](MachineInstr *DeadMI) {
- WorkListObserver.erasingInstr(*DeadMI);
+ LegalizationArtifactCombiner ArtCombiner(*MIRBuilder.get(), MF.getRegInfo(),
+ LInfo);
+ auto RemoveDeadInstFromLists = [&WrapperObserver](MachineInstr *DeadMI) {
+ WrapperObserver.erasingInstr(*DeadMI);
};
bool Changed = false;
do {