diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt index 5759fd9736e78..cbe0f30aeadcd 100644 --- a/llvm/lib/Target/Mips/CMakeLists.txt +++ b/llvm/lib/Target/Mips/CMakeLists.txt @@ -9,6 +9,8 @@ tablegen(LLVM MipsGenDAGISel.inc -gen-dag-isel) tablegen(LLVM MipsGenDisassemblerTables.inc -gen-disassembler) tablegen(LLVM MipsGenFastISel.inc -gen-fast-isel) tablegen(LLVM MipsGenGlobalISel.inc -gen-global-isel) +tablegen(LLVM MipsGenPostLegalizeGICombiner.inc -gen-global-isel-combiner + -combiners="MipsPostLegalizerCombinerHelper") tablegen(LLVM MipsGenInstrInfo.inc -gen-instr-info) tablegen(LLVM MipsGenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM MipsGenMCPseudoLowering.inc -gen-pseudo-lowering) @@ -48,6 +50,7 @@ add_llvm_target(MipsCodeGen MipsOptimizePICCall.cpp MipsOs16.cpp MipsPreLegalizerCombiner.cpp + MipsPostLegalizerCombiner.cpp MipsRegisterBankInfo.cpp MipsRegisterInfo.cpp MipsSEFrameLowering.cpp diff --git a/llvm/lib/Target/Mips/Mips.h b/llvm/lib/Target/Mips/Mips.h index faf58545db626..12dc29bbfe855 100644 --- a/llvm/lib/Target/Mips/Mips.h +++ b/llvm/lib/Target/Mips/Mips.h @@ -38,6 +38,7 @@ namespace llvm { FunctionPass *createMicroMipsSizeReducePass(); FunctionPass *createMipsExpandPseudoPass(); FunctionPass *createMipsPreLegalizeCombiner(); + FunctionPass *createMipsPostLegalizeCombiner(bool IsOptNone); FunctionPass *createMipsMulMulBugPass(); InstructionSelector *createMipsInstructionSelector(const MipsTargetMachine &, @@ -48,6 +49,7 @@ namespace llvm { void initializeMipsBranchExpansionPass(PassRegistry &); void initializeMicroMipsSizeReducePass(PassRegistry &); void initializeMipsPreLegalizerCombinerPass(PassRegistry&); + void initializeMipsPostLegalizerCombinerPass(PassRegistry &); void initializeMipsMulMulBugFixPass(PassRegistry&); } // end namespace llvm; diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td index 792960332bcc7..406760dc678c8 100644 --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -217,6 +217,7 @@ include "MipsSchedule.td" include "MipsInstrInfo.td" include "MipsCallingConv.td" include "MipsRegisterBanks.td" +include "MipsCombine.td" // Avoid forward declaration issues. include "MipsScheduleP5600.td" diff --git a/llvm/lib/Target/Mips/MipsCombine.td b/llvm/lib/Target/Mips/MipsCombine.td new file mode 100644 index 0000000000000..29550a15d38d2 --- /dev/null +++ b/llvm/lib/Target/Mips/MipsCombine.td @@ -0,0 +1,15 @@ +//=- MipsCombine.td - Define Mips Combine Rules --------------*- tablegen -*-=// +// +// 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 +// +//===----------------------------------------------------------------------===// + +include "llvm/Target/GlobalISel/Combine.td" + +def MipsPostLegalizerCombinerHelper: GICombinerHelper< + "MipsGenPostLegalizerCombinerHelper", []> { + let DisableRuleOption = "mipspostlegalizercombiner-disable-rule"; +} + diff --git a/llvm/lib/Target/Mips/MipsPostLegalizerCombiner.cpp b/llvm/lib/Target/Mips/MipsPostLegalizerCombiner.cpp new file mode 100644 index 0000000000000..7723a10af2d71 --- /dev/null +++ b/llvm/lib/Target/Mips/MipsPostLegalizerCombiner.cpp @@ -0,0 +1,148 @@ +//=== lib/CodeGen/GlobalISel/MipsPostLegalizerCombiner.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, +// after the legalizer. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/MipsMCTargetDesc.h" +#include "Mips.h" +#include "MipsLegalizerInfo.h" +#include "MipsSubtarget.h" +#include "llvm/CodeGen/GlobalISel/Combiner.h" +#include "llvm/CodeGen/GlobalISel/CombinerHelper.h" +#include "llvm/CodeGen/GlobalISel/CombinerInfo.h" +#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" +#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/Target/TargetMachine.h" + +#define DEBUG_TYPE "mips-postlegalizer-combiner" + +using namespace llvm; +using namespace MIPatternMatch; + +#define MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS +#include "MipsGenPostLegalizeGICombiner.inc" +#undef MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS + +namespace { +#define MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H +#include "MipsGenPostLegalizeGICombiner.inc" +#undef MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H + +class MipsPostLegalizerCombinerInfo final : public CombinerInfo { + GISelKnownBits *KB; + +public: + MipsGenPostLegalizerCombinerHelperRuleConfig GeneratedRuleCfg; + + MipsPostLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize, + GISelKnownBits *KB, const MipsLegalizerInfo *LI) + : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true, + /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize), + KB(KB) { + if (!GeneratedRuleCfg.parseCommandLineOption()) + report_fatal_error("Invalid rule identifier"); + } + + bool combine(GISelChangeObserver &Observer, MachineInstr &MI, + MachineIRBuilder &B) const override; +}; + +bool MipsPostLegalizerCombinerInfo::combine(GISelChangeObserver &Observer, + MachineInstr &MI, + MachineIRBuilder &B) const { + + CombinerHelper Helper(Observer, B, KB, + /*DominatorTree*/ nullptr, LInfo); + MipsGenPostLegalizerCombinerHelper Generated(GeneratedRuleCfg, Helper); + return Generated.tryCombineAll(Observer, MI, B, Helper); +} + +#define MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP +#include "MipsGenPostLegalizeGICombiner.inc" +#undef MIPSPOSTLEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP + +// Pass boilerplate +// ================ + +class MipsPostLegalizerCombiner : public MachineFunctionPass { +public: + static char ID; + + MipsPostLegalizerCombiner(bool IsOptNone = false); + + StringRef getPassName() const override { + return "MipsPostLegalizerCombiner"; + } + + bool runOnMachineFunction(MachineFunction &MF) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; + +private: + bool IsOptNone; +}; +} // end anonymous namespace + +void MipsPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesCFG(); + getSelectionDAGFallbackAnalysisUsage(AU); + AU.addRequired(); + AU.addPreserved(); + if (!IsOptNone) { + AU.addRequired(); + AU.addPreserved(); + } + MachineFunctionPass::getAnalysisUsage(AU); +} + +MipsPostLegalizerCombiner::MipsPostLegalizerCombiner(bool IsOptNone) + : MachineFunctionPass(ID), IsOptNone(IsOptNone) { + initializeMipsPostLegalizerCombinerPass(*PassRegistry::getPassRegistry()); +} + +bool MipsPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) { + if (MF.getProperties().hasProperty( + MachineFunctionProperties::Property::FailedISel)) + return false; + auto *TPC = &getAnalysis(); + const Function &F = MF.getFunction(); + bool EnableOpt = + MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F); + + const MipsSubtarget &ST = MF.getSubtarget(); + const MipsLegalizerInfo *LI = + static_cast(ST.getLegalizerInfo()); + + GISelKnownBits *KB = &getAnalysis().get(MF); + MipsPostLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(), + F.hasMinSize(), KB, LI); + Combiner C(PCInfo, TPC); + return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr); +} + +char MipsPostLegalizerCombiner::ID = 0; +INITIALIZE_PASS_BEGIN(MipsPostLegalizerCombiner, DEBUG_TYPE, + "Combine Mips machine instrs after legalization", false, + false) +INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) +INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis) +INITIALIZE_PASS_END(MipsPostLegalizerCombiner, DEBUG_TYPE, + "Combine Mips machine instrs after legalization", false, + false) + +namespace llvm { +FunctionPass *createMipsPostLegalizeCombiner(bool IsOptNone) { + return new MipsPostLegalizerCombiner(IsOptNone); +} +} // end namespace llvm diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp index f309cbb5c8dab..9b8a4f0b85176 100644 --- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp +++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp @@ -63,6 +63,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() { initializeMipsBranchExpansionPass(*PR); initializeMicroMipsSizeReducePass(*PR); initializeMipsPreLegalizerCombinerPass(*PR); + initializeMipsPostLegalizerCombinerPass(*PR); initializeMipsMulMulBugFixPass(*PR); } @@ -239,6 +240,7 @@ class MipsPassConfig : public TargetPassConfig { bool addIRTranslator() override; void addPreLegalizeMachineIR() override; bool addLegalizeMachineIR() override; + void addPreRegBankSelect() override; bool addRegBankSelect() override; bool addGlobalInstructionSelect() override; @@ -334,6 +336,11 @@ bool MipsPassConfig::addLegalizeMachineIR() { return false; } +void MipsPassConfig::addPreRegBankSelect() { + bool IsOptNone = getOptLevel() == CodeGenOpt::None; + addPass(createMipsPostLegalizeCombiner(IsOptNone)); +} + bool MipsPassConfig::addRegBankSelect() { addPass(new RegBankSelect()); return false;