1 //=== lib/CodeGen/GlobalISel/AArch64PreLegalizerCombiner.cpp --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass does combining of machine instructions at the generic MI level,
11 // before the legalizer.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "AArch64TargetMachine.h"
16 #include "llvm/CodeGen/GlobalISel/Combiner.h"
17 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
18 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
19 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/TargetPassConfig.h"
22 #include "llvm/Support/Debug.h"
23 
24 #define DEBUG_TYPE "aarch64-prelegalizer-combiner"
25 
26 using namespace llvm;
27 using namespace MIPatternMatch;
28 
29 namespace {
30 class AArch64PreLegalizerCombinerInfo : public CombinerInfo {
31 public:
AArch64PreLegalizerCombinerInfo()32   AArch64PreLegalizerCombinerInfo()
33       : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
34                      /*LegalizerInfo*/ nullptr) {}
35   virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
36                        MachineIRBuilder &B) const override;
37 };
38 
combine(GISelChangeObserver & Observer,MachineInstr & MI,MachineIRBuilder & B) const39 bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
40                                               MachineInstr &MI,
41                                               MachineIRBuilder &B) const {
42   CombinerHelper Helper(Observer, B);
43 
44   switch (MI.getOpcode()) {
45   default:
46     return false;
47   case TargetOpcode::G_LOAD:
48   case TargetOpcode::G_SEXTLOAD:
49   case TargetOpcode::G_ZEXTLOAD:
50     return Helper.tryCombineExtendingLoads(MI);
51   }
52 
53   return false;
54 }
55 
56 // Pass boilerplate
57 // ================
58 
59 class AArch64PreLegalizerCombiner : public MachineFunctionPass {
60 public:
61   static char ID;
62 
63   AArch64PreLegalizerCombiner();
64 
getPassName() const65   StringRef getPassName() const override { return "AArch64PreLegalizerCombiner"; }
66 
67   bool runOnMachineFunction(MachineFunction &MF) override;
68 
69   void getAnalysisUsage(AnalysisUsage &AU) const override;
70 };
71 }
72 
getAnalysisUsage(AnalysisUsage & AU) const73 void AArch64PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
74   AU.addRequired<TargetPassConfig>();
75   AU.setPreservesCFG();
76   getSelectionDAGFallbackAnalysisUsage(AU);
77   MachineFunctionPass::getAnalysisUsage(AU);
78 }
79 
AArch64PreLegalizerCombiner()80 AArch64PreLegalizerCombiner::AArch64PreLegalizerCombiner() : MachineFunctionPass(ID) {
81   initializeAArch64PreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
82 }
83 
runOnMachineFunction(MachineFunction & MF)84 bool AArch64PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
85   if (MF.getProperties().hasProperty(
86           MachineFunctionProperties::Property::FailedISel))
87     return false;
88   auto *TPC = &getAnalysis<TargetPassConfig>();
89   AArch64PreLegalizerCombinerInfo PCInfo;
90   Combiner C(PCInfo, TPC);
91   return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
92 }
93 
94 char AArch64PreLegalizerCombiner::ID = 0;
95 INITIALIZE_PASS_BEGIN(AArch64PreLegalizerCombiner, DEBUG_TYPE,
96                       "Combine AArch64 machine instrs before legalization",
97                       false, false)
98 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
99 INITIALIZE_PASS_END(AArch64PreLegalizerCombiner, DEBUG_TYPE,
100                     "Combine AArch64 machine instrs before legalization", false,
101                     false)
102 
103 
104 namespace llvm {
createAArch64PreLegalizeCombiner()105 FunctionPass *createAArch64PreLegalizeCombiner() {
106   return new AArch64PreLegalizerCombiner();
107 }
108 } // end namespace llvm
109