xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUPreLegalizerCombiner.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
15ffd83dbSDimitry Andric //=== lib/CodeGen/GlobalISel/AMDGPUPreLegalizerCombiner.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 // before the legalizer.
115ffd83dbSDimitry Andric //
125ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
135ffd83dbSDimitry Andric 
14*e8d8bef9SDimitry Andric #include "AMDGPU.h"
155ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h"
165ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
175ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
185ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
195ffd83dbSDimitry Andric #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
205ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
215ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
22*e8d8bef9SDimitry Andric #include "llvm/Target/TargetMachine.h"
235ffd83dbSDimitry Andric 
245ffd83dbSDimitry Andric #define DEBUG_TYPE "amdgpu-prelegalizer-combiner"
255ffd83dbSDimitry Andric 
265ffd83dbSDimitry Andric using namespace llvm;
275ffd83dbSDimitry Andric using namespace MIPatternMatch;
285ffd83dbSDimitry Andric 
295ffd83dbSDimitry Andric #define AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS
305ffd83dbSDimitry Andric #include "AMDGPUGenPreLegalizeGICombiner.inc"
315ffd83dbSDimitry Andric #undef AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS
325ffd83dbSDimitry Andric 
335ffd83dbSDimitry Andric namespace {
345ffd83dbSDimitry Andric #define AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H
355ffd83dbSDimitry Andric #include "AMDGPUGenPreLegalizeGICombiner.inc"
365ffd83dbSDimitry Andric #undef AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H
375ffd83dbSDimitry Andric 
38*e8d8bef9SDimitry Andric class AMDGPUPreLegalizerCombinerInfo final : public CombinerInfo {
395ffd83dbSDimitry Andric   GISelKnownBits *KB;
405ffd83dbSDimitry Andric   MachineDominatorTree *MDT;
415ffd83dbSDimitry Andric 
425ffd83dbSDimitry Andric public:
435ffd83dbSDimitry Andric   AMDGPUGenPreLegalizerCombinerHelperRuleConfig GeneratedRuleCfg;
445ffd83dbSDimitry Andric 
455ffd83dbSDimitry Andric   AMDGPUPreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
465ffd83dbSDimitry Andric                                   GISelKnownBits *KB, MachineDominatorTree *MDT)
475ffd83dbSDimitry Andric       : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
485ffd83dbSDimitry Andric                      /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize),
495ffd83dbSDimitry Andric         KB(KB), MDT(MDT) {
505ffd83dbSDimitry Andric     if (!GeneratedRuleCfg.parseCommandLineOption())
515ffd83dbSDimitry Andric       report_fatal_error("Invalid rule identifier");
525ffd83dbSDimitry Andric   }
535ffd83dbSDimitry Andric 
545ffd83dbSDimitry Andric   virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
555ffd83dbSDimitry Andric                        MachineIRBuilder &B) const override;
565ffd83dbSDimitry Andric };
575ffd83dbSDimitry Andric 
585ffd83dbSDimitry Andric bool AMDGPUPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
595ffd83dbSDimitry Andric                                               MachineInstr &MI,
605ffd83dbSDimitry Andric                                               MachineIRBuilder &B) const {
615ffd83dbSDimitry Andric   CombinerHelper Helper(Observer, B, KB, MDT);
625ffd83dbSDimitry Andric   AMDGPUGenPreLegalizerCombinerHelper Generated(GeneratedRuleCfg);
635ffd83dbSDimitry Andric 
645ffd83dbSDimitry Andric   if (Generated.tryCombineAll(Observer, MI, B, Helper))
655ffd83dbSDimitry Andric     return true;
665ffd83dbSDimitry Andric 
675ffd83dbSDimitry Andric   switch (MI.getOpcode()) {
685ffd83dbSDimitry Andric   case TargetOpcode::G_CONCAT_VECTORS:
695ffd83dbSDimitry Andric     return Helper.tryCombineConcatVectors(MI);
705ffd83dbSDimitry Andric   case TargetOpcode::G_SHUFFLE_VECTOR:
715ffd83dbSDimitry Andric     return Helper.tryCombineShuffleVector(MI);
725ffd83dbSDimitry Andric   }
735ffd83dbSDimitry Andric 
745ffd83dbSDimitry Andric   return false;
755ffd83dbSDimitry Andric }
765ffd83dbSDimitry Andric 
775ffd83dbSDimitry Andric #define AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP
785ffd83dbSDimitry Andric #include "AMDGPUGenPreLegalizeGICombiner.inc"
795ffd83dbSDimitry Andric #undef AMDGPUPRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP
805ffd83dbSDimitry Andric 
815ffd83dbSDimitry Andric // Pass boilerplate
825ffd83dbSDimitry Andric // ================
835ffd83dbSDimitry Andric 
845ffd83dbSDimitry Andric class AMDGPUPreLegalizerCombiner : public MachineFunctionPass {
855ffd83dbSDimitry Andric public:
865ffd83dbSDimitry Andric   static char ID;
875ffd83dbSDimitry Andric 
885ffd83dbSDimitry Andric   AMDGPUPreLegalizerCombiner(bool IsOptNone = false);
895ffd83dbSDimitry Andric 
905ffd83dbSDimitry Andric   StringRef getPassName() const override {
915ffd83dbSDimitry Andric     return "AMDGPUPreLegalizerCombiner";
925ffd83dbSDimitry Andric   }
935ffd83dbSDimitry Andric 
945ffd83dbSDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
955ffd83dbSDimitry Andric 
965ffd83dbSDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
975ffd83dbSDimitry Andric private:
985ffd83dbSDimitry Andric   bool IsOptNone;
995ffd83dbSDimitry Andric };
1005ffd83dbSDimitry Andric } // end anonymous namespace
1015ffd83dbSDimitry Andric 
1025ffd83dbSDimitry Andric void AMDGPUPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
1035ffd83dbSDimitry Andric   AU.addRequired<TargetPassConfig>();
1045ffd83dbSDimitry Andric   AU.setPreservesCFG();
1055ffd83dbSDimitry Andric   getSelectionDAGFallbackAnalysisUsage(AU);
1065ffd83dbSDimitry Andric   AU.addRequired<GISelKnownBitsAnalysis>();
1075ffd83dbSDimitry Andric   AU.addPreserved<GISelKnownBitsAnalysis>();
1085ffd83dbSDimitry Andric   if (!IsOptNone) {
1095ffd83dbSDimitry Andric     AU.addRequired<MachineDominatorTree>();
1105ffd83dbSDimitry Andric     AU.addPreserved<MachineDominatorTree>();
1115ffd83dbSDimitry Andric   }
1125ffd83dbSDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
1135ffd83dbSDimitry Andric }
1145ffd83dbSDimitry Andric 
1155ffd83dbSDimitry Andric AMDGPUPreLegalizerCombiner::AMDGPUPreLegalizerCombiner(bool IsOptNone)
1165ffd83dbSDimitry Andric   : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
1175ffd83dbSDimitry Andric   initializeAMDGPUPreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
1185ffd83dbSDimitry Andric }
1195ffd83dbSDimitry Andric 
1205ffd83dbSDimitry Andric bool AMDGPUPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
1215ffd83dbSDimitry Andric   if (MF.getProperties().hasProperty(
1225ffd83dbSDimitry Andric           MachineFunctionProperties::Property::FailedISel))
1235ffd83dbSDimitry Andric     return false;
1245ffd83dbSDimitry Andric   auto *TPC = &getAnalysis<TargetPassConfig>();
1255ffd83dbSDimitry Andric   const Function &F = MF.getFunction();
1265ffd83dbSDimitry Andric   bool EnableOpt =
1275ffd83dbSDimitry Andric       MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
1285ffd83dbSDimitry Andric   GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
1295ffd83dbSDimitry Andric   MachineDominatorTree *MDT =
1305ffd83dbSDimitry Andric       IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>();
1315ffd83dbSDimitry Andric   AMDGPUPreLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
1325ffd83dbSDimitry Andric                                         F.hasMinSize(), KB, MDT);
1335ffd83dbSDimitry Andric   Combiner C(PCInfo, TPC);
1345ffd83dbSDimitry Andric   return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
1355ffd83dbSDimitry Andric }
1365ffd83dbSDimitry Andric 
1375ffd83dbSDimitry Andric char AMDGPUPreLegalizerCombiner::ID = 0;
1385ffd83dbSDimitry Andric INITIALIZE_PASS_BEGIN(AMDGPUPreLegalizerCombiner, DEBUG_TYPE,
1395ffd83dbSDimitry Andric                       "Combine AMDGPU machine instrs before legalization",
1405ffd83dbSDimitry Andric                       false, false)
1415ffd83dbSDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
1425ffd83dbSDimitry Andric INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
1435ffd83dbSDimitry Andric INITIALIZE_PASS_END(AMDGPUPreLegalizerCombiner, DEBUG_TYPE,
1445ffd83dbSDimitry Andric                     "Combine AMDGPU machine instrs before legalization", false,
1455ffd83dbSDimitry Andric                     false)
1465ffd83dbSDimitry Andric 
1475ffd83dbSDimitry Andric namespace llvm {
1485ffd83dbSDimitry Andric FunctionPass *createAMDGPUPreLegalizeCombiner(bool IsOptNone) {
1495ffd83dbSDimitry Andric   return new AMDGPUPreLegalizerCombiner(IsOptNone);
1505ffd83dbSDimitry Andric }
1515ffd83dbSDimitry Andric } // end namespace llvm
152