diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/CodeGen/CSEConfigBase.h | 28 | ||||
-rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h | 34 | ||||
-rw-r--r-- | llvm/include/llvm/CodeGen/TargetPassConfig.h | 4 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/Legalizer.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetPassConfig.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64TargetMachine.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMTargetMachine.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsTargetMachine.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86TargetMachine.cpp | 6 | ||||
-rw-r--r-- | llvm/unittests/CodeGen/GlobalISel/CSETest.cpp | 2 |
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()); |