summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/CSEConfigBase.h28
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h34
-rw-r--r--llvm/include/llvm/CodeGen/TargetPassConfig.h4
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp20
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp3
-rw-r--r--llvm/lib/CodeGen/GlobalISel/Legalizer.cpp3
-rw-r--r--llvm/lib/CodeGen/TargetPassConfig.cpp5
-rw-r--r--llvm/lib/Target/AArch64/AArch64TargetMachine.cpp7
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp6
-rw-r--r--llvm/lib/Target/ARM/ARMTargetMachine.cpp6
-rw-r--r--llvm/lib/Target/Mips/MipsTargetMachine.cpp6
-rw-r--r--llvm/lib/Target/X86/X86TargetMachine.cpp6
-rw-r--r--llvm/unittests/CodeGen/GlobalISel/CSETest.cpp2
13 files changed, 107 insertions, 23 deletions
diff --git a/llvm/include/llvm/CodeGen/CSEConfigBase.h b/llvm/include/llvm/CodeGen/CSEConfigBase.h
new file mode 100644
index 00000000000..70b5e5c17eb
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/CSEConfigBase.h
@@ -0,0 +1,28 @@
+//===- CSEConfigBase.h - A CSEConfig interface ------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_CSECONFIG_BASE_H
+#define LLVM_CODEGEN_CSECONFIG_BASE_H
+
+namespace llvm {
+// Class representing some configuration that can be done during GlobalISel's
+// CSEInfo analysis. We define it here because TargetPassConfig can't depend on
+// the GlobalISel library, and so we use this in the interface between them
+// so that the derived classes in GISel can reference generic opcodes.
+class CSEConfigBase {
+public:
+ virtual ~CSEConfigBase() = default;
+ // Hook for defining which Generic instructions should be CSEd.
+ // GISelCSEInfo currently only calls this hook when dealing with generic
+ // opcodes.
+ virtual bool shouldCSEOpc(unsigned Opc) { return false; }
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_CSECONFIG_BASE_H
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
index 97f3cd5c95b..5a44e67992a 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
@@ -13,6 +13,7 @@
#define LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/CodeGen/CSEConfigBase.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
@@ -36,25 +37,27 @@ public:
void Profile(FoldingSetNodeID &ID);
};
-// Class representing some configuration that can be done during CSE analysis.
-// Currently it only supports shouldCSE method that each pass can set.
-class CSEConfig {
+// A CSE config for fully optimized builds.
+class CSEConfigFull : public CSEConfigBase {
public:
- virtual ~CSEConfig() = default;
- // Hook for defining which Generic instructions should be CSEd.
- // GISelCSEInfo currently only calls this hook when dealing with generic
- // opcodes.
- virtual bool shouldCSEOpc(unsigned Opc);
+ virtual ~CSEConfigFull() = default;
+ virtual bool shouldCSEOpc(unsigned Opc) override;
};
-// TODO: Find a better place for this.
// Commonly used for O0 config.
-class CSEConfigConstantOnly : public CSEConfig {
+class CSEConfigConstantOnly : public CSEConfigBase {
public:
virtual ~CSEConfigConstantOnly() = default;
virtual bool shouldCSEOpc(unsigned Opc) override;
};
+// Returns the standard expected CSEConfig for the given optimization level.
+// We have this logic here so targets can make use of it from their derived
+// TargetPassConfig, but can't put this logic into TargetPassConfig directly
+// because the CodeGen library can't depend on GlobalISel.
+std::unique_ptr<CSEConfigBase>
+getStandardCSEConfigForOpt(CodeGenOpt::Level Level);
+
/// The CSE Analysis object.
/// This installs itself as a delegate to the MachineFunction to track
/// new instructions as well as deletions. It however will not be able to
@@ -73,7 +76,7 @@ class GISelCSEInfo : public GISelChangeObserver {
FoldingSet<UniqueMachineInstr> CSEMap;
MachineRegisterInfo *MRI = nullptr;
MachineFunction *MF = nullptr;
- std::unique_ptr<CSEConfig> CSEOpt;
+ std::unique_ptr<CSEConfigBase> CSEOpt;
/// Keep a cache of UniqueInstrs for each MachineInstr. In GISel,
/// often instructions are mutated (while their ID has completely changed).
/// Whenever mutation happens, invalidate the UniqueMachineInstr for the
@@ -138,7 +141,9 @@ public:
void releaseMemory();
- void setCSEConfig(std::unique_ptr<CSEConfig> Opt) { CSEOpt = std::move(Opt); }
+ void setCSEConfig(std::unique_ptr<CSEConfigBase> Opt) {
+ CSEOpt = std::move(Opt);
+ }
bool shouldCSE(unsigned Opc) const;
@@ -198,11 +203,12 @@ class GISelCSEAnalysisWrapper {
bool AlreadyComputed = false;
public:
- /// Takes a CSEConfig object that defines what opcodes get CSEd.
+ /// Takes a CSEConfigBase object that defines what opcodes get CSEd.
/// If CSEConfig is already set, and the CSE Analysis has been preserved,
/// it will not use the new CSEOpt(use Recompute to force using the new
/// CSEOpt).
- GISelCSEInfo &get(std::unique_ptr<CSEConfig> CSEOpt, bool ReCompute = false);
+ GISelCSEInfo &get(std::unique_ptr<CSEConfigBase> CSEOpt,
+ bool ReCompute = false);
void setMF(MachineFunction &MFunc) { MF = &MFunc; }
void setComputed(bool Computed) { AlreadyComputed = Computed; }
void releaseMemory() { Info.releaseMemory(); }
diff --git a/llvm/include/llvm/CodeGen/TargetPassConfig.h b/llvm/include/llvm/CodeGen/TargetPassConfig.h
index 80a26845eeb..8623e7bb079 100644
--- a/llvm/include/llvm/CodeGen/TargetPassConfig.h
+++ b/llvm/include/llvm/CodeGen/TargetPassConfig.h
@@ -24,6 +24,7 @@ class LLVMTargetMachine;
struct MachineSchedContext;
class PassConfigImpl;
class ScheduleDAGInstrs;
+class CSEConfigBase;
// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
@@ -319,6 +320,9 @@ public:
/// By default, it's enabled for non O0 levels.
virtual bool isGISelCSEEnabled() const;
+ /// Returns the CSEConfig object to use for the current optimization level.
+ virtual std::unique_ptr<CSEConfigBase> getCSEConfig() const;
+
protected:
// Helper to verify the analysis is really immutable.
void setOpt(bool &Opt, bool Val);
diff --git a/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp b/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
index aaf09c8c938..a87ef20a3be 100644
--- a/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp
@@ -27,8 +27,8 @@ void UniqueMachineInstr::Profile(FoldingSetNodeID &ID) {
}
/// -----------------------------------------
-/// --------- CSEConfig ---------- ///
-bool CSEConfig::shouldCSEOpc(unsigned Opc) {
+/// --------- CSEConfigFull ---------- ///
+bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
switch (Opc) {
default:
break;
@@ -60,6 +60,17 @@ bool CSEConfig::shouldCSEOpc(unsigned Opc) {
bool CSEConfigConstantOnly::shouldCSEOpc(unsigned Opc) {
return Opc == TargetOpcode::G_CONSTANT;
}
+
+std::unique_ptr<CSEConfigBase>
+llvm::getStandardCSEConfigForOpt(CodeGenOpt::Level Level) {
+ std::unique_ptr<CSEConfigBase> Config;
+ if (Level == CodeGenOpt::None)
+ Config = make_unique<CSEConfigBase>();
+ else
+ Config = make_unique<CSEConfigFull>();
+ return Config;
+}
+
/// -----------------------------------------
/// -------- GISelCSEInfo -------------//
@@ -348,8 +359,9 @@ const GISelInstProfileBuilder &GISelInstProfileBuilder::addNodeIDMachineOperand(
return *this;
}
-GISelCSEInfo &GISelCSEAnalysisWrapper::get(std::unique_ptr<CSEConfig> CSEOpt,
- bool Recompute) {
+GISelCSEInfo &
+GISelCSEAnalysisWrapper::get(std::unique_ptr<CSEConfigBase> CSEOpt,
+ bool Recompute) {
if (!AlreadyComputed || Recompute) {
Info.setCSEConfig(std::move(CSEOpt));
Info.analyze(*MF);
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 290d592339f..2e268ed27a9 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1729,8 +1729,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
if (EnableCSE) {
EntryBuilder = make_unique<CSEMIRBuilder>(CurMF);
- std::unique_ptr<CSEConfig> Config = make_unique<CSEConfig>();
- CSEInfo = &Wrapper.get(std::move(Config));
+ CSEInfo = &Wrapper.get(TPC->getCSEConfig());
EntryBuilder->setCSEInfo(CSEInfo);
CurBuilder = make_unique<CSEMIRBuilder>(CurMF);
CurBuilder->setCSEInfo(CSEInfo);
diff --git a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
index 4db86761cdb..efdae5790ab 100644
--- a/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
@@ -170,8 +170,7 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
if (EnableCSE) {
MIRBuilder = make_unique<CSEMIRBuilder>();
- std::unique_ptr<CSEConfig> Config = make_unique<CSEConfig>();
- CSEInfo = &Wrapper.get(std::move(Config));
+ CSEInfo = &Wrapper.get(TPC.getCSEConfig());
MIRBuilder->setCSEInfo(CSEInfo);
} else
MIRBuilder = make_unique<MachineIRBuilder>();
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 8ddde4b8f99..e5c7ceff112 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -22,6 +22,7 @@
#include "llvm/Analysis/ScopedNoAliasAA.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
+#include "llvm/CodeGen/CSEConfigBase.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/Passes.h"
@@ -1227,3 +1228,7 @@ bool TargetPassConfig::reportDiagnosticWhenGlobalISelFallback() const {
bool TargetPassConfig::isGISelCSEEnabled() const {
return getOptLevel() != CodeGenOpt::Level::None;
}
+
+std::unique_ptr<CSEConfigBase> TargetPassConfig::getCSEConfig() const {
+ return make_unique<CSEConfigBase>();
+}
diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
index d213f20755f..d657fd414f3 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -19,6 +19,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/CSEConfigBase.h"
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
@@ -383,6 +384,8 @@ public:
void addPostRegAlloc() override;
void addPreSched2() override;
void addPreEmitPass() override;
+
+ std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
};
} // end anonymous namespace
@@ -396,6 +399,10 @@ TargetPassConfig *AArch64TargetMachine::createPassConfig(PassManagerBase &PM) {
return new AArch64PassConfig(*this, PM);
}
+std::unique_ptr<CSEConfigBase> AArch64PassConfig::getCSEConfig() const {
+ return getStandardCSEConfigForOpt(TM->getOptLevel());
+}
+
void AArch64PassConfig::addIRPasses() {
// Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
// ourselves.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index 8dd467b8d96..f2408819ce9 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -552,8 +552,14 @@ public:
bool addPreISel() override;
bool addInstSelector() override;
bool addGCPasses() override;
+
+ std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
};
+std::unique_ptr<CSEConfigBase> AMDGPUPassConfig::getCSEConfig() const {
+ return getStandardCSEConfigForOpt(TM->getOptLevel());
+}
+
class R600PassConfig final : public AMDGPUPassConfig {
public:
R600PassConfig(LLVMTargetMachine &TM, PassManagerBase &PM)
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index d2663ac912d..3c38b4584e8 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -361,6 +361,8 @@ public:
void addPreRegAlloc() override;
void addPreSched2() override;
void addPreEmitPass() override;
+
+ std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
};
class ARMExecutionDomainFix : public ExecutionDomainFix {
@@ -385,6 +387,10 @@ TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
return new ARMPassConfig(*this, PM);
}
+std::unique_ptr<CSEConfigBase> ARMPassConfig::getCSEConfig() const {
+ return getStandardCSEConfigForOpt(TM->getOptLevel());
+}
+
void ARMPassConfig::addIRPasses() {
if (TM->Options.ThreadModel == ThreadModel::Single)
addPass(createLowerAtomicPass());
diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
index 92ba00db1c3..591e2c4b706 100644
--- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp
@@ -239,6 +239,8 @@ public:
bool addLegalizeMachineIR() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
+
+ std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
};
} // end anonymous namespace
@@ -247,6 +249,10 @@ TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
return new MipsPassConfig(*this, PM);
}
+std::unique_ptr<CSEConfigBase> MipsPassConfig::getCSEConfig() const {
+ return getStandardCSEConfigForOpt(TM->getOptLevel());
+}
+
void MipsPassConfig::addIRPasses() {
TargetPassConfig::addIRPasses();
addPass(createAtomicExpandPass());
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index d0006650cf8..73fb57a1f19 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -377,6 +377,8 @@ public:
void addPreEmitPass() override;
void addPreEmitPass2() override;
void addPreSched2() override;
+
+ std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
};
class X86ExecutionDomainFix : public ExecutionDomainFix {
@@ -520,3 +522,7 @@ void X86PassConfig::addPreEmitPass2() {
if (!TT.isOSDarwin() && !TT.isOSWindows())
addPass(createCFIInstrInserter());
}
+
+std::unique_ptr<CSEConfigBase> X86PassConfig::getCSEConfig() const {
+ return getStandardCSEConfigForOpt(TM->getOptLevel());
+}
diff --git a/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp b/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
index 02627cae164..f2f755b23a0 100644
--- a/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/CSETest.cpp
@@ -21,7 +21,7 @@ TEST_F(GISelMITest, TestCSE) {
auto MIBInput1 = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[1]});
auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
GISelCSEInfo CSEInfo;
- CSEInfo.setCSEConfig(make_unique<CSEConfig>());
+ CSEInfo.setCSEConfig(make_unique<CSEConfigFull>());
CSEInfo.analyze(*MF);
B.setCSEInfo(&CSEInfo);
CSEMIRBuilder CSEB(B.getState());
OpenPOWER on IntegriCloud