1 //=== lib/CodeGen/GlobalISel/AArch64O0PreLegalizerCombiner.cpp ------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This pass does combining of machine instructions at the generic MI level,
10 // before the legalizer.
12 //===----------------------------------------------------------------------===//
14 #include "AArch64GlobalISelUtils.h"
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/GISelKnownBits.h"
20 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
21 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
22 #include "llvm/CodeGen/MachineDominators.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/TargetPassConfig.h"
27 #include "llvm/IR/Instructions.h"
28 #include "llvm/Support/Debug.h"
30 #define DEBUG_TYPE "aarch64-O0-prelegalizer-combiner"
33 using namespace MIPatternMatch
;
35 class AArch64O0PreLegalizerCombinerHelperState
{
37 CombinerHelper
&Helper
;
40 AArch64O0PreLegalizerCombinerHelperState(CombinerHelper
&Helper
)
44 #define AARCH64O0PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS
45 #include "AArch64GenO0PreLegalizeGICombiner.inc"
46 #undef AARCH64O0PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_DEPS
49 #define AARCH64O0PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H
50 #include "AArch64GenO0PreLegalizeGICombiner.inc"
51 #undef AARCH64O0PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_H
53 class AArch64O0PreLegalizerCombinerInfo
: public CombinerInfo
{
55 MachineDominatorTree
*MDT
;
56 AArch64GenO0PreLegalizerCombinerHelperRuleConfig GeneratedRuleCfg
;
59 AArch64O0PreLegalizerCombinerInfo(bool EnableOpt
, bool OptSize
, bool MinSize
,
61 MachineDominatorTree
*MDT
)
62 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
63 /*LegalizerInfo*/ nullptr, EnableOpt
, OptSize
, MinSize
),
65 if (!GeneratedRuleCfg
.parseCommandLineOption())
66 report_fatal_error("Invalid rule identifier");
69 virtual bool combine(GISelChangeObserver
&Observer
, MachineInstr
&MI
,
70 MachineIRBuilder
&B
) const override
;
73 bool AArch64O0PreLegalizerCombinerInfo::combine(GISelChangeObserver
&Observer
,
75 MachineIRBuilder
&B
) const {
76 CombinerHelper
Helper(Observer
, B
, KB
, MDT
);
77 AArch64GenO0PreLegalizerCombinerHelper
Generated(GeneratedRuleCfg
, Helper
);
79 if (Generated
.tryCombineAll(Observer
, MI
, B
))
82 unsigned Opc
= MI
.getOpcode();
84 case TargetOpcode::G_CONCAT_VECTORS
:
85 return Helper
.tryCombineConcatVectors(MI
);
86 case TargetOpcode::G_SHUFFLE_VECTOR
:
87 return Helper
.tryCombineShuffleVector(MI
);
88 case TargetOpcode::G_MEMCPY_INLINE
:
89 return Helper
.tryEmitMemcpyInline(MI
);
90 case TargetOpcode::G_MEMCPY
:
91 case TargetOpcode::G_MEMMOVE
:
92 case TargetOpcode::G_MEMSET
: {
93 // At -O0 set a maxlen of 32 to inline;
95 // Try to inline memcpy type calls if optimizations are enabled.
96 if (Helper
.tryCombineMemCpyFamily(MI
, MaxLen
))
98 if (Opc
== TargetOpcode::G_MEMSET
)
99 return llvm::AArch64GISelUtils::tryEmitBZero(MI
, B
, EnableMinSize
);
107 #define AARCH64O0PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP
108 #include "AArch64GenO0PreLegalizeGICombiner.inc"
109 #undef AARCH64O0PRELEGALIZERCOMBINERHELPER_GENCOMBINERHELPER_CPP
114 class AArch64O0PreLegalizerCombiner
: public MachineFunctionPass
{
118 AArch64O0PreLegalizerCombiner();
120 StringRef
getPassName() const override
{
121 return "AArch64O0PreLegalizerCombiner";
124 bool runOnMachineFunction(MachineFunction
&MF
) override
;
126 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
128 } // end anonymous namespace
130 void AArch64O0PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage
&AU
) const {
131 AU
.addRequired
<TargetPassConfig
>();
132 AU
.setPreservesCFG();
133 getSelectionDAGFallbackAnalysisUsage(AU
);
134 AU
.addRequired
<GISelKnownBitsAnalysis
>();
135 AU
.addPreserved
<GISelKnownBitsAnalysis
>();
136 MachineFunctionPass::getAnalysisUsage(AU
);
139 AArch64O0PreLegalizerCombiner::AArch64O0PreLegalizerCombiner()
140 : MachineFunctionPass(ID
) {
141 initializeAArch64O0PreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
144 bool AArch64O0PreLegalizerCombiner::runOnMachineFunction(MachineFunction
&MF
) {
145 if (MF
.getProperties().hasProperty(
146 MachineFunctionProperties::Property::FailedISel
))
148 auto &TPC
= getAnalysis
<TargetPassConfig
>();
150 const Function
&F
= MF
.getFunction();
151 GISelKnownBits
*KB
= &getAnalysis
<GISelKnownBitsAnalysis
>().get(MF
);
152 AArch64O0PreLegalizerCombinerInfo
PCInfo(
153 false, F
.hasOptSize(), F
.hasMinSize(), KB
, nullptr /* MDT */);
154 Combiner
C(PCInfo
, &TPC
);
155 return C
.combineMachineInstrs(MF
, nullptr /* CSEInfo */);
158 char AArch64O0PreLegalizerCombiner::ID
= 0;
159 INITIALIZE_PASS_BEGIN(AArch64O0PreLegalizerCombiner
, DEBUG_TYPE
,
160 "Combine AArch64 machine instrs before legalization",
162 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig
)
163 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis
)
164 INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass
)
165 INITIALIZE_PASS_END(AArch64O0PreLegalizerCombiner
, DEBUG_TYPE
,
166 "Combine AArch64 machine instrs before legalization", false,
170 FunctionPass
*createAArch64O0PreLegalizerCombiner() {
171 return new AArch64O0PreLegalizerCombiner();
173 } // end namespace llvm