xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
15ffd83dbSDimitry Andric //=== lib/CodeGen/GlobalISel/AMDGPURegBankCombiner.cpp ---------------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric //
95ffd83dbSDimitry Andric // This pass does combining of machine instructions at the generic MI level,
105ffd83dbSDimitry Andric // after register banks are known.
115ffd83dbSDimitry Andric //
125ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
135ffd83dbSDimitry Andric 
14*e8d8bef9SDimitry Andric #include "AMDGPU.h"
155ffd83dbSDimitry Andric #include "AMDGPULegalizerInfo.h"
16*e8d8bef9SDimitry Andric #include "GCNSubtarget.h"
175ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h"
185ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
195ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
205ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
215ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
225ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
235ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
24*e8d8bef9SDimitry Andric #include "llvm/Target/TargetMachine.h"
255ffd83dbSDimitry Andric #define DEBUG_TYPE "amdgpu-regbank-combiner"
265ffd83dbSDimitry Andric 
275ffd83dbSDimitry Andric using namespace llvm;
285ffd83dbSDimitry Andric using namespace MIPatternMatch;
295ffd83dbSDimitry Andric 
305ffd83dbSDimitry Andric 
315ffd83dbSDimitry Andric #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_DEPS
325ffd83dbSDimitry Andric #include "AMDGPUGenRegBankGICombiner.inc"
335ffd83dbSDimitry Andric #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_DEPS
345ffd83dbSDimitry Andric 
355ffd83dbSDimitry Andric namespace {
365ffd83dbSDimitry Andric #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_H
375ffd83dbSDimitry Andric #include "AMDGPUGenRegBankGICombiner.inc"
385ffd83dbSDimitry Andric #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_H
395ffd83dbSDimitry Andric 
40*e8d8bef9SDimitry Andric class AMDGPURegBankCombinerInfo final : public CombinerInfo {
415ffd83dbSDimitry Andric   GISelKnownBits *KB;
425ffd83dbSDimitry Andric   MachineDominatorTree *MDT;
435ffd83dbSDimitry Andric 
445ffd83dbSDimitry Andric public:
455ffd83dbSDimitry Andric   AMDGPUGenRegBankCombinerHelperRuleConfig GeneratedRuleCfg;
465ffd83dbSDimitry Andric 
475ffd83dbSDimitry Andric   AMDGPURegBankCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
485ffd83dbSDimitry Andric                                   const AMDGPULegalizerInfo *LI,
495ffd83dbSDimitry Andric                                   GISelKnownBits *KB, MachineDominatorTree *MDT)
505ffd83dbSDimitry Andric       : CombinerInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true,
515ffd83dbSDimitry Andric                      /*LegalizerInfo*/ LI, EnableOpt, OptSize, MinSize),
525ffd83dbSDimitry Andric         KB(KB), MDT(MDT) {
535ffd83dbSDimitry Andric     if (!GeneratedRuleCfg.parseCommandLineOption())
545ffd83dbSDimitry Andric       report_fatal_error("Invalid rule identifier");
555ffd83dbSDimitry Andric   }
565ffd83dbSDimitry Andric 
575ffd83dbSDimitry Andric   bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
585ffd83dbSDimitry Andric                MachineIRBuilder &B) const override;
595ffd83dbSDimitry Andric };
605ffd83dbSDimitry Andric 
615ffd83dbSDimitry Andric bool AMDGPURegBankCombinerInfo::combine(GISelChangeObserver &Observer,
625ffd83dbSDimitry Andric                                               MachineInstr &MI,
635ffd83dbSDimitry Andric                                               MachineIRBuilder &B) const {
645ffd83dbSDimitry Andric   CombinerHelper Helper(Observer, B, KB, MDT);
655ffd83dbSDimitry Andric   AMDGPUGenRegBankCombinerHelper Generated(GeneratedRuleCfg);
665ffd83dbSDimitry Andric 
675ffd83dbSDimitry Andric   if (Generated.tryCombineAll(Observer, MI, B, Helper))
685ffd83dbSDimitry Andric     return true;
695ffd83dbSDimitry Andric 
705ffd83dbSDimitry Andric   return false;
715ffd83dbSDimitry Andric }
725ffd83dbSDimitry Andric 
735ffd83dbSDimitry Andric #define AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_CPP
745ffd83dbSDimitry Andric #include "AMDGPUGenRegBankGICombiner.inc"
755ffd83dbSDimitry Andric #undef AMDGPUREGBANKCOMBINERHELPER_GENCOMBINERHELPER_CPP
765ffd83dbSDimitry Andric 
775ffd83dbSDimitry Andric // Pass boilerplate
785ffd83dbSDimitry Andric // ================
795ffd83dbSDimitry Andric 
805ffd83dbSDimitry Andric class AMDGPURegBankCombiner : public MachineFunctionPass {
815ffd83dbSDimitry Andric public:
825ffd83dbSDimitry Andric   static char ID;
835ffd83dbSDimitry Andric 
845ffd83dbSDimitry Andric   AMDGPURegBankCombiner(bool IsOptNone = false);
855ffd83dbSDimitry Andric 
865ffd83dbSDimitry Andric   StringRef getPassName() const override {
875ffd83dbSDimitry Andric     return "AMDGPURegBankCombiner";
885ffd83dbSDimitry Andric   }
895ffd83dbSDimitry Andric 
905ffd83dbSDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
915ffd83dbSDimitry Andric 
925ffd83dbSDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
935ffd83dbSDimitry Andric private:
945ffd83dbSDimitry Andric   bool IsOptNone;
955ffd83dbSDimitry Andric };
965ffd83dbSDimitry Andric } // end anonymous namespace
975ffd83dbSDimitry Andric 
985ffd83dbSDimitry Andric void AMDGPURegBankCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
995ffd83dbSDimitry Andric   AU.addRequired<TargetPassConfig>();
1005ffd83dbSDimitry Andric   AU.setPreservesCFG();
1015ffd83dbSDimitry Andric   getSelectionDAGFallbackAnalysisUsage(AU);
1025ffd83dbSDimitry Andric   AU.addRequired<GISelKnownBitsAnalysis>();
1035ffd83dbSDimitry Andric   AU.addPreserved<GISelKnownBitsAnalysis>();
1045ffd83dbSDimitry Andric   if (!IsOptNone) {
1055ffd83dbSDimitry Andric     AU.addRequired<MachineDominatorTree>();
1065ffd83dbSDimitry Andric     AU.addPreserved<MachineDominatorTree>();
1075ffd83dbSDimitry Andric   }
1085ffd83dbSDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1095ffd83dbSDimitry Andric }
1105ffd83dbSDimitry Andric 
1115ffd83dbSDimitry Andric AMDGPURegBankCombiner::AMDGPURegBankCombiner(bool IsOptNone)
1125ffd83dbSDimitry Andric   : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
1135ffd83dbSDimitry Andric   initializeAMDGPURegBankCombinerPass(*PassRegistry::getPassRegistry());
1145ffd83dbSDimitry Andric }
1155ffd83dbSDimitry Andric 
1165ffd83dbSDimitry Andric bool AMDGPURegBankCombiner::runOnMachineFunction(MachineFunction &MF) {
1175ffd83dbSDimitry Andric   if (MF.getProperties().hasProperty(
1185ffd83dbSDimitry Andric           MachineFunctionProperties::Property::FailedISel))
1195ffd83dbSDimitry Andric     return false;
1205ffd83dbSDimitry Andric   auto *TPC = &getAnalysis<TargetPassConfig>();
1215ffd83dbSDimitry Andric   const Function &F = MF.getFunction();
1225ffd83dbSDimitry Andric   bool EnableOpt =
1235ffd83dbSDimitry Andric       MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
1245ffd83dbSDimitry Andric 
1255ffd83dbSDimitry Andric   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
1265ffd83dbSDimitry Andric   const AMDGPULegalizerInfo *LI
1275ffd83dbSDimitry Andric     = static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo());
1285ffd83dbSDimitry Andric 
1295ffd83dbSDimitry Andric   GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
1305ffd83dbSDimitry Andric   MachineDominatorTree *MDT =
1315ffd83dbSDimitry Andric       IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>();
1325ffd83dbSDimitry Andric   AMDGPURegBankCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
1335ffd83dbSDimitry Andric                                          F.hasMinSize(), LI, KB, MDT);
1345ffd83dbSDimitry Andric   Combiner C(PCInfo, TPC);
1355ffd83dbSDimitry Andric   return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
1365ffd83dbSDimitry Andric }
1375ffd83dbSDimitry Andric 
1385ffd83dbSDimitry Andric char AMDGPURegBankCombiner::ID = 0;
1395ffd83dbSDimitry Andric INITIALIZE_PASS_BEGIN(AMDGPURegBankCombiner, DEBUG_TYPE,
1405ffd83dbSDimitry Andric                       "Combine AMDGPU machine instrs after regbankselect",
1415ffd83dbSDimitry Andric                       false, false)
1425ffd83dbSDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
1435ffd83dbSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
1445ffd83dbSDimitry Andric INITIALIZE_PASS_END(AMDGPURegBankCombiner, DEBUG_TYPE,
1455ffd83dbSDimitry Andric                     "Combine AMDGPU machine instrs after regbankselect", false,
1465ffd83dbSDimitry Andric                     false)
1475ffd83dbSDimitry Andric 
1485ffd83dbSDimitry Andric namespace llvm {
1495ffd83dbSDimitry Andric FunctionPass *createAMDGPURegBankCombiner(bool IsOptNone) {
1505ffd83dbSDimitry Andric   return new AMDGPURegBankCombiner(IsOptNone);
1515ffd83dbSDimitry Andric }
1525ffd83dbSDimitry Andric } // end namespace llvm
153