xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsPreLegalizerCombiner.cpp (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
10b57cec5SDimitry Andric //=== lib/CodeGen/GlobalISel/MipsPreLegalizerCombiner.cpp --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This pass does combining of machine instructions at the generic MI level,
100b57cec5SDimitry Andric // before the legalizer.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "MipsTargetMachine.h"
150b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Combiner.h"
160b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
170b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
20*480093f4SDimitry Andric #include "llvm/InitializePasses.h"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #define DEBUG_TYPE "mips-prelegalizer-combiner"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using namespace llvm;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace {
270b57cec5SDimitry Andric class MipsPreLegalizerCombinerInfo : public CombinerInfo {
280b57cec5SDimitry Andric public:
290b57cec5SDimitry Andric   MipsPreLegalizerCombinerInfo()
300b57cec5SDimitry Andric       : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
318bcb0991SDimitry Andric                      /*LegalizerInfo*/ nullptr, /*EnableOpt*/ false,
328bcb0991SDimitry Andric                      /*EnableOptSize*/ false, /*EnableMinSize*/ false) {}
330b57cec5SDimitry Andric   virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
340b57cec5SDimitry Andric                        MachineIRBuilder &B) const override;
350b57cec5SDimitry Andric };
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric bool MipsPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
380b57cec5SDimitry Andric                                            MachineInstr &MI,
390b57cec5SDimitry Andric                                            MachineIRBuilder &B) const {
400b57cec5SDimitry Andric   CombinerHelper Helper(Observer, B);
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   switch (MI.getOpcode()) {
430b57cec5SDimitry Andric   default:
440b57cec5SDimitry Andric     return false;
450b57cec5SDimitry Andric   case TargetOpcode::G_LOAD:
460b57cec5SDimitry Andric   case TargetOpcode::G_SEXTLOAD:
470b57cec5SDimitry Andric   case TargetOpcode::G_ZEXTLOAD:
480b57cec5SDimitry Andric     return Helper.tryCombineExtendingLoads(MI);
490b57cec5SDimitry Andric   }
500b57cec5SDimitry Andric   return false;
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric // Pass boilerplate
540b57cec5SDimitry Andric // ================
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric class MipsPreLegalizerCombiner : public MachineFunctionPass {
570b57cec5SDimitry Andric public:
580b57cec5SDimitry Andric   static char ID;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   MipsPreLegalizerCombiner();
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   StringRef getPassName() const override { return "MipsPreLegalizerCombiner"; }
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
670b57cec5SDimitry Andric };
680b57cec5SDimitry Andric } // end anonymous namespace
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric void MipsPreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
710b57cec5SDimitry Andric   AU.addRequired<TargetPassConfig>();
720b57cec5SDimitry Andric   AU.setPreservesCFG();
730b57cec5SDimitry Andric   getSelectionDAGFallbackAnalysisUsage(AU);
740b57cec5SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric MipsPreLegalizerCombiner::MipsPreLegalizerCombiner() : MachineFunctionPass(ID) {
780b57cec5SDimitry Andric   initializeMipsPreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric bool MipsPreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
820b57cec5SDimitry Andric   if (MF.getProperties().hasProperty(
830b57cec5SDimitry Andric           MachineFunctionProperties::Property::FailedISel))
840b57cec5SDimitry Andric     return false;
850b57cec5SDimitry Andric   auto *TPC = &getAnalysis<TargetPassConfig>();
860b57cec5SDimitry Andric   MipsPreLegalizerCombinerInfo PCInfo;
870b57cec5SDimitry Andric   Combiner C(PCInfo, TPC);
880b57cec5SDimitry Andric   return C.combineMachineInstrs(MF, nullptr);
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric char MipsPreLegalizerCombiner::ID = 0;
920b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(MipsPreLegalizerCombiner, DEBUG_TYPE,
930b57cec5SDimitry Andric                       "Combine Mips machine instrs before legalization", false,
940b57cec5SDimitry Andric                       false)
950b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
960b57cec5SDimitry Andric INITIALIZE_PASS_END(MipsPreLegalizerCombiner, DEBUG_TYPE,
970b57cec5SDimitry Andric                     "Combine Mips machine instrs before legalization", false,
980b57cec5SDimitry Andric                     false)
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric namespace llvm {
1010b57cec5SDimitry Andric FunctionPass *createMipsPreLegalizeCombiner() {
1020b57cec5SDimitry Andric   return new MipsPreLegalizerCombiner();
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric } // end namespace llvm
105