There are a number of backends (specifically AArch64, AMDGPU, Mips, and RISCV) which contain a “TODO: make CombinerHelper methods const” comment. This PR does just that and makes all of the CombinerHelper methods const, removes the TODO comments and makes the associated instances const. This change makes some sense because the CombinerHelper class simply modifies the state of _other_ objects to which it holds pointers or references. Note that AMDGPU contains an identical comment for an instance of AMDGPUCombinerHelper (a subclass of CombinerHelper). I deliberately haven’t modified the methods of that class in order to limit the scope of the change. I’m happy to do so either now or as a follow-up.
175 lines
6.1 KiB
C++
175 lines
6.1 KiB
C++
//=== RISCVPreLegalizerCombiner.cpp ---------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This pass does combining of machine instructions at the generic MI level,
|
|
// before the legalizer.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "RISCVSubtarget.h"
|
|
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
|
|
#include "llvm/CodeGen/GlobalISel/Combiner.h"
|
|
#include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
|
|
#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
|
|
#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
|
|
#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
|
|
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
|
#include "llvm/CodeGen/MachineDominators.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/CodeGen/TargetPassConfig.h"
|
|
|
|
#define GET_GICOMBINER_DEPS
|
|
#include "RISCVGenPreLegalizeGICombiner.inc"
|
|
#undef GET_GICOMBINER_DEPS
|
|
|
|
#define DEBUG_TYPE "riscv-prelegalizer-combiner"
|
|
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
|
|
#define GET_GICOMBINER_TYPES
|
|
#include "RISCVGenPreLegalizeGICombiner.inc"
|
|
#undef GET_GICOMBINER_TYPES
|
|
|
|
class RISCVPreLegalizerCombinerImpl : public Combiner {
|
|
protected:
|
|
const CombinerHelper Helper;
|
|
const RISCVPreLegalizerCombinerImplRuleConfig &RuleConfig;
|
|
const RISCVSubtarget &STI;
|
|
|
|
public:
|
|
RISCVPreLegalizerCombinerImpl(
|
|
MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
|
|
GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
|
|
const RISCVPreLegalizerCombinerImplRuleConfig &RuleConfig,
|
|
const RISCVSubtarget &STI, MachineDominatorTree *MDT,
|
|
const LegalizerInfo *LI);
|
|
|
|
static const char *getName() { return "RISCV00PreLegalizerCombiner"; }
|
|
|
|
bool tryCombineAll(MachineInstr &I) const override;
|
|
|
|
private:
|
|
#define GET_GICOMBINER_CLASS_MEMBERS
|
|
#include "RISCVGenPreLegalizeGICombiner.inc"
|
|
#undef GET_GICOMBINER_CLASS_MEMBERS
|
|
};
|
|
|
|
#define GET_GICOMBINER_IMPL
|
|
#include "RISCVGenPreLegalizeGICombiner.inc"
|
|
#undef GET_GICOMBINER_IMPL
|
|
|
|
RISCVPreLegalizerCombinerImpl::RISCVPreLegalizerCombinerImpl(
|
|
MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC,
|
|
GISelKnownBits &KB, GISelCSEInfo *CSEInfo,
|
|
const RISCVPreLegalizerCombinerImplRuleConfig &RuleConfig,
|
|
const RISCVSubtarget &STI, MachineDominatorTree *MDT,
|
|
const LegalizerInfo *LI)
|
|
: Combiner(MF, CInfo, TPC, &KB, CSEInfo),
|
|
Helper(Observer, B, /*IsPreLegalize*/ true, &KB, MDT, LI),
|
|
RuleConfig(RuleConfig), STI(STI),
|
|
#define GET_GICOMBINER_CONSTRUCTOR_INITS
|
|
#include "RISCVGenPreLegalizeGICombiner.inc"
|
|
#undef GET_GICOMBINER_CONSTRUCTOR_INITS
|
|
{
|
|
}
|
|
|
|
// Pass boilerplate
|
|
// ================
|
|
|
|
class RISCVPreLegalizerCombiner : public MachineFunctionPass {
|
|
public:
|
|
static char ID;
|
|
|
|
RISCVPreLegalizerCombiner();
|
|
|
|
StringRef getPassName() const override { return "RISCVPreLegalizerCombiner"; }
|
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override;
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
|
|
|
private:
|
|
RISCVPreLegalizerCombinerImplRuleConfig RuleConfig;
|
|
};
|
|
} // end anonymous namespace
|
|
|
|
void RISCVPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
|
|
AU.addRequired<TargetPassConfig>();
|
|
AU.setPreservesCFG();
|
|
getSelectionDAGFallbackAnalysisUsage(AU);
|
|
AU.addRequired<GISelKnownBitsAnalysis>();
|
|
AU.addPreserved<GISelKnownBitsAnalysis>();
|
|
AU.addRequired<MachineDominatorTreeWrapperPass>();
|
|
AU.addPreserved<MachineDominatorTreeWrapperPass>();
|
|
AU.addRequired<GISelCSEAnalysisWrapperPass>();
|
|
AU.addPreserved<GISelCSEAnalysisWrapperPass>();
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
}
|
|
|
|
RISCVPreLegalizerCombiner::RISCVPreLegalizerCombiner()
|
|
: MachineFunctionPass(ID) {
|
|
initializeRISCVPreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
|
|
|
|
if (!RuleConfig.parseCommandLineOption())
|
|
report_fatal_error("Invalid rule identifier");
|
|
}
|
|
|
|
bool RISCVPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
|
|
if (MF.getProperties().hasProperty(
|
|
MachineFunctionProperties::Property::FailedISel))
|
|
return false;
|
|
auto &TPC = getAnalysis<TargetPassConfig>();
|
|
|
|
// Enable CSE.
|
|
GISelCSEAnalysisWrapper &Wrapper =
|
|
getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
|
|
auto *CSEInfo = &Wrapper.get(TPC.getCSEConfig());
|
|
|
|
const RISCVSubtarget &ST = MF.getSubtarget<RISCVSubtarget>();
|
|
const auto *LI = ST.getLegalizerInfo();
|
|
|
|
const Function &F = MF.getFunction();
|
|
bool EnableOpt =
|
|
MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
|
|
GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
|
|
MachineDominatorTree *MDT =
|
|
&getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
|
|
CombinerInfo CInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
|
|
/*LegalizerInfo*/ nullptr, EnableOpt, F.hasOptSize(),
|
|
F.hasMinSize());
|
|
// Disable fixed-point iteration to reduce compile-time
|
|
CInfo.MaxIterations = 1;
|
|
CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
|
|
// This is the first Combiner, so the input IR might contain dead
|
|
// instructions.
|
|
CInfo.EnableFullDCE = true;
|
|
RISCVPreLegalizerCombinerImpl Impl(MF, CInfo, &TPC, *KB, CSEInfo, RuleConfig,
|
|
ST, MDT, LI);
|
|
return Impl.combineMachineInstrs();
|
|
}
|
|
|
|
char RISCVPreLegalizerCombiner::ID = 0;
|
|
INITIALIZE_PASS_BEGIN(RISCVPreLegalizerCombiner, DEBUG_TYPE,
|
|
"Combine RISC-V machine instrs before legalization", false,
|
|
false)
|
|
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
|
|
INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
|
|
INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
|
|
INITIALIZE_PASS_END(RISCVPreLegalizerCombiner, DEBUG_TYPE,
|
|
"Combine RISC-V machine instrs before legalization", false,
|
|
false)
|
|
|
|
namespace llvm {
|
|
FunctionPass *createRISCVPreLegalizerCombiner() {
|
|
return new RISCVPreLegalizerCombiner();
|
|
}
|
|
} // end namespace llvm
|