Skip to content

Commit d189680

Browse files
committed
[GlobalISel] Introduce a CSEConfigBase class to allow targets to define their own CSE configs.
Because CodeGen can't depend on GlobalISel, we need a way to encapsulate the CSE configs that can be passed between TargetPassConfig and the targets' custom pass configs. This CSEConfigBase allows targets to create custom CSE configs which is then used by the GISel passes for the CSEMIRBuilder. This support will be used in a follow up commit to allow constant-only CSE for -O0 compiles in D60580. llvm-svn: 358368
1 parent ae050d2 commit d189680

File tree

13 files changed

+107
-23
lines changed

13 files changed

+107
-23
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===- CSEConfigBase.h - A CSEConfig interface ------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CODEGEN_CSECONFIG_BASE_H
10+
#define LLVM_CODEGEN_CSECONFIG_BASE_H
11+
12+
namespace llvm {
13+
// Class representing some configuration that can be done during GlobalISel's
14+
// CSEInfo analysis. We define it here because TargetPassConfig can't depend on
15+
// the GlobalISel library, and so we use this in the interface between them
16+
// so that the derived classes in GISel can reference generic opcodes.
17+
class CSEConfigBase {
18+
public:
19+
virtual ~CSEConfigBase() = default;
20+
// Hook for defining which Generic instructions should be CSEd.
21+
// GISelCSEInfo currently only calls this hook when dealing with generic
22+
// opcodes.
23+
virtual bool shouldCSEOpc(unsigned Opc) { return false; }
24+
};
25+
26+
} // namespace llvm
27+
28+
#endif // LLVM_CODEGEN_CSECONFIG_BASE_H

llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
1414

1515
#include "llvm/ADT/FoldingSet.h"
16+
#include "llvm/CodeGen/CSEConfigBase.h"
1617
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
1718
#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
1819
#include "llvm/CodeGen/GlobalISel/Utils.h"
@@ -36,25 +37,27 @@ class UniqueMachineInstr : public FoldingSetNode {
3637
void Profile(FoldingSetNodeID &ID);
3738
};
3839

39-
// Class representing some configuration that can be done during CSE analysis.
40-
// Currently it only supports shouldCSE method that each pass can set.
41-
class CSEConfig {
40+
// A CSE config for fully optimized builds.
41+
class CSEConfigFull : public CSEConfigBase {
4242
public:
43-
virtual ~CSEConfig() = default;
44-
// Hook for defining which Generic instructions should be CSEd.
45-
// GISelCSEInfo currently only calls this hook when dealing with generic
46-
// opcodes.
47-
virtual bool shouldCSEOpc(unsigned Opc);
43+
virtual ~CSEConfigFull() = default;
44+
virtual bool shouldCSEOpc(unsigned Opc) override;
4845
};
4946

50-
// TODO: Find a better place for this.
5147
// Commonly used for O0 config.
52-
class CSEConfigConstantOnly : public CSEConfig {
48+
class CSEConfigConstantOnly : public CSEConfigBase {
5349
public:
5450
virtual ~CSEConfigConstantOnly() = default;
5551
virtual bool shouldCSEOpc(unsigned Opc) override;
5652
};
5753

54+
// Returns the standard expected CSEConfig for the given optimization level.
55+
// We have this logic here so targets can make use of it from their derived
56+
// TargetPassConfig, but can't put this logic into TargetPassConfig directly
57+
// because the CodeGen library can't depend on GlobalISel.
58+
std::unique_ptr<CSEConfigBase>
59+
getStandardCSEConfigForOpt(CodeGenOpt::Level Level);
60+
5861
/// The CSE Analysis object.
5962
/// This installs itself as a delegate to the MachineFunction to track
6063
/// new instructions as well as deletions. It however will not be able to
@@ -73,7 +76,7 @@ class GISelCSEInfo : public GISelChangeObserver {
7376
FoldingSet<UniqueMachineInstr> CSEMap;
7477
MachineRegisterInfo *MRI = nullptr;
7578
MachineFunction *MF = nullptr;
76-
std::unique_ptr<CSEConfig> CSEOpt;
79+
std::unique_ptr<CSEConfigBase> CSEOpt;
7780
/// Keep a cache of UniqueInstrs for each MachineInstr. In GISel,
7881
/// often instructions are mutated (while their ID has completely changed).
7982
/// Whenever mutation happens, invalidate the UniqueMachineInstr for the
@@ -138,7 +141,9 @@ class GISelCSEInfo : public GISelChangeObserver {
138141

139142
void releaseMemory();
140143

141-
void setCSEConfig(std::unique_ptr<CSEConfig> Opt) { CSEOpt = std::move(Opt); }
144+
void setCSEConfig(std::unique_ptr<CSEConfigBase> Opt) {
145+
CSEOpt = std::move(Opt);
146+
}
142147

143148
bool shouldCSE(unsigned Opc) const;
144149

@@ -198,11 +203,12 @@ class GISelCSEAnalysisWrapper {
198203
bool AlreadyComputed = false;
199204

200205
public:
201-
/// Takes a CSEConfig object that defines what opcodes get CSEd.
206+
/// Takes a CSEConfigBase object that defines what opcodes get CSEd.
202207
/// If CSEConfig is already set, and the CSE Analysis has been preserved,
203208
/// it will not use the new CSEOpt(use Recompute to force using the new
204209
/// CSEOpt).
205-
GISelCSEInfo &get(std::unique_ptr<CSEConfig> CSEOpt, bool ReCompute = false);
210+
GISelCSEInfo &get(std::unique_ptr<CSEConfigBase> CSEOpt,
211+
bool ReCompute = false);
206212
void setMF(MachineFunction &MFunc) { MF = &MFunc; }
207213
void setComputed(bool Computed) { AlreadyComputed = Computed; }
208214
void releaseMemory() { Info.releaseMemory(); }

llvm/include/llvm/CodeGen/TargetPassConfig.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class LLVMTargetMachine;
2424
struct MachineSchedContext;
2525
class PassConfigImpl;
2626
class ScheduleDAGInstrs;
27+
class CSEConfigBase;
2728

2829
// The old pass manager infrastructure is hidden in a legacy namespace now.
2930
namespace legacy {
@@ -319,6 +320,9 @@ class TargetPassConfig : public ImmutablePass {
319320
/// By default, it's enabled for non O0 levels.
320321
virtual bool isGISelCSEEnabled() const;
321322

323+
/// Returns the CSEConfig object to use for the current optimization level.
324+
virtual std::unique_ptr<CSEConfigBase> getCSEConfig() const;
325+
322326
protected:
323327
// Helper to verify the analysis is really immutable.
324328
void setOpt(bool &Opt, bool Val);

llvm/lib/CodeGen/GlobalISel/CSEInfo.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ void UniqueMachineInstr::Profile(FoldingSetNodeID &ID) {
2727
}
2828
/// -----------------------------------------
2929

30-
/// --------- CSEConfig ---------- ///
31-
bool CSEConfig::shouldCSEOpc(unsigned Opc) {
30+
/// --------- CSEConfigFull ---------- ///
31+
bool CSEConfigFull::shouldCSEOpc(unsigned Opc) {
3232
switch (Opc) {
3333
default:
3434
break;
@@ -60,6 +60,17 @@ bool CSEConfig::shouldCSEOpc(unsigned Opc) {
6060
bool CSEConfigConstantOnly::shouldCSEOpc(unsigned Opc) {
6161
return Opc == TargetOpcode::G_CONSTANT;
6262
}
63+
64+
std::unique_ptr<CSEConfigBase>
65+
llvm::getStandardCSEConfigForOpt(CodeGenOpt::Level Level) {
66+
std::unique_ptr<CSEConfigBase> Config;
67+
if (Level == CodeGenOpt::None)
68+
Config = make_unique<CSEConfigBase>();
69+
else
70+
Config = make_unique<CSEConfigFull>();
71+
return Config;
72+
}
73+
6374
/// -----------------------------------------
6475

6576
/// -------- GISelCSEInfo -------------//
@@ -348,8 +359,9 @@ const GISelInstProfileBuilder &GISelInstProfileBuilder::addNodeIDMachineOperand(
348359
return *this;
349360
}
350361

351-
GISelCSEInfo &GISelCSEAnalysisWrapper::get(std::unique_ptr<CSEConfig> CSEOpt,
352-
bool Recompute) {
362+
GISelCSEInfo &
363+
GISelCSEAnalysisWrapper::get(std::unique_ptr<CSEConfigBase> CSEOpt,
364+
bool Recompute) {
353365
if (!AlreadyComputed || Recompute) {
354366
Info.setCSEConfig(std::move(CSEOpt));
355367
Info.analyze(*MF);

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,8 +1729,7 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
17291729

17301730
if (EnableCSE) {
17311731
EntryBuilder = make_unique<CSEMIRBuilder>(CurMF);
1732-
std::unique_ptr<CSEConfig> Config = make_unique<CSEConfig>();
1733-
CSEInfo = &Wrapper.get(std::move(Config));
1732+
CSEInfo = &Wrapper.get(TPC->getCSEConfig());
17341733
EntryBuilder->setCSEInfo(CSEInfo);
17351734
CurBuilder = make_unique<CSEMIRBuilder>(CurMF);
17361735
CurBuilder->setCSEInfo(CSEInfo);

llvm/lib/CodeGen/GlobalISel/Legalizer.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
170170

171171
if (EnableCSE) {
172172
MIRBuilder = make_unique<CSEMIRBuilder>();
173-
std::unique_ptr<CSEConfig> Config = make_unique<CSEConfig>();
174-
CSEInfo = &Wrapper.get(std::move(Config));
173+
CSEInfo = &Wrapper.get(TPC.getCSEConfig());
175174
MIRBuilder->setCSEInfo(CSEInfo);
176175
} else
177176
MIRBuilder = make_unique<MachineIRBuilder>();

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/Analysis/ScopedNoAliasAA.h"
2323
#include "llvm/Analysis/TargetTransformInfo.h"
2424
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
25+
#include "llvm/CodeGen/CSEConfigBase.h"
2526
#include "llvm/CodeGen/MachineFunctionPass.h"
2627
#include "llvm/CodeGen/MachinePassRegistry.h"
2728
#include "llvm/CodeGen/Passes.h"
@@ -1227,3 +1228,7 @@ bool TargetPassConfig::reportDiagnosticWhenGlobalISelFallback() const {
12271228
bool TargetPassConfig::isGISelCSEEnabled() const {
12281229
return getOptLevel() != CodeGenOpt::Level::None;
12291230
}
1231+
1232+
std::unique_ptr<CSEConfigBase> TargetPassConfig::getCSEConfig() const {
1233+
return make_unique<CSEConfigBase>();
1234+
}

llvm/lib/Target/AArch64/AArch64TargetMachine.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/STLExtras.h"
2020
#include "llvm/ADT/Triple.h"
2121
#include "llvm/Analysis/TargetTransformInfo.h"
22+
#include "llvm/CodeGen/CSEConfigBase.h"
2223
#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
2324
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
2425
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
@@ -383,6 +384,8 @@ class AArch64PassConfig : public TargetPassConfig {
383384
void addPostRegAlloc() override;
384385
void addPreSched2() override;
385386
void addPreEmitPass() override;
387+
388+
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
386389
};
387390

388391
} // end anonymous namespace
@@ -396,6 +399,10 @@ TargetPassConfig *AArch64TargetMachine::createPassConfig(PassManagerBase &PM) {
396399
return new AArch64PassConfig(*this, PM);
397400
}
398401

402+
std::unique_ptr<CSEConfigBase> AArch64PassConfig::getCSEConfig() const {
403+
return getStandardCSEConfigForOpt(TM->getOptLevel());
404+
}
405+
399406
void AArch64PassConfig::addIRPasses() {
400407
// Always expand atomic operations, we don't deal with atomicrmw or cmpxchg
401408
// ourselves.

llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,14 @@ class AMDGPUPassConfig : public TargetPassConfig {
552552
bool addPreISel() override;
553553
bool addInstSelector() override;
554554
bool addGCPasses() override;
555+
556+
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
555557
};
556558

559+
std::unique_ptr<CSEConfigBase> AMDGPUPassConfig::getCSEConfig() const {
560+
return getStandardCSEConfigForOpt(TM->getOptLevel());
561+
}
562+
557563
class R600PassConfig final : public AMDGPUPassConfig {
558564
public:
559565
R600PassConfig(LLVMTargetMachine &TM, PassManagerBase &PM)

llvm/lib/Target/ARM/ARMTargetMachine.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,8 @@ class ARMPassConfig : public TargetPassConfig {
361361
void addPreRegAlloc() override;
362362
void addPreSched2() override;
363363
void addPreEmitPass() override;
364+
365+
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
364366
};
365367

366368
class ARMExecutionDomainFix : public ExecutionDomainFix {
@@ -385,6 +387,10 @@ TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM) {
385387
return new ARMPassConfig(*this, PM);
386388
}
387389

390+
std::unique_ptr<CSEConfigBase> ARMPassConfig::getCSEConfig() const {
391+
return getStandardCSEConfigForOpt(TM->getOptLevel());
392+
}
393+
388394
void ARMPassConfig::addIRPasses() {
389395
if (TM->Options.ThreadModel == ThreadModel::Single)
390396
addPass(createLowerAtomicPass());

llvm/lib/Target/Mips/MipsTargetMachine.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ class MipsPassConfig : public TargetPassConfig {
239239
bool addLegalizeMachineIR() override;
240240
bool addRegBankSelect() override;
241241
bool addGlobalInstructionSelect() override;
242+
243+
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
242244
};
243245

244246
} // end anonymous namespace
@@ -247,6 +249,10 @@ TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
247249
return new MipsPassConfig(*this, PM);
248250
}
249251

252+
std::unique_ptr<CSEConfigBase> MipsPassConfig::getCSEConfig() const {
253+
return getStandardCSEConfigForOpt(TM->getOptLevel());
254+
}
255+
250256
void MipsPassConfig::addIRPasses() {
251257
TargetPassConfig::addIRPasses();
252258
addPass(createAtomicExpandPass());

llvm/lib/Target/X86/X86TargetMachine.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ class X86PassConfig : public TargetPassConfig {
377377
void addPreEmitPass() override;
378378
void addPreEmitPass2() override;
379379
void addPreSched2() override;
380+
381+
std::unique_ptr<CSEConfigBase> getCSEConfig() const override;
380382
};
381383

382384
class X86ExecutionDomainFix : public ExecutionDomainFix {
@@ -520,3 +522,7 @@ void X86PassConfig::addPreEmitPass2() {
520522
if (!TT.isOSDarwin() && !TT.isOSWindows())
521523
addPass(createCFIInstrInserter());
522524
}
525+
526+
std::unique_ptr<CSEConfigBase> X86PassConfig::getCSEConfig() const {
527+
return getStandardCSEConfigForOpt(TM->getOptLevel());
528+
}

llvm/unittests/CodeGen/GlobalISel/CSETest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ TEST_F(GISelMITest, TestCSE) {
2121
auto MIBInput1 = B.buildInstr(TargetOpcode::G_TRUNC, {s16}, {Copies[1]});
2222
auto MIBAdd = B.buildInstr(TargetOpcode::G_ADD, {s16}, {MIBInput, MIBInput});
2323
GISelCSEInfo CSEInfo;
24-
CSEInfo.setCSEConfig(make_unique<CSEConfig>());
24+
CSEInfo.setCSEConfig(make_unique<CSEConfigFull>());
2525
CSEInfo.analyze(*MF);
2626
B.setCSEInfo(&CSEInfo);
2727
CSEMIRBuilder CSEB(B.getState());

0 commit comments

Comments
 (0)