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