1 //=== lib/CodeGen/GlobalISel/AArch64PreLegalizerCombiner.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 "AArch64TargetMachine.h"
15 #include "llvm/CodeGen/GlobalISel/Combiner.h"
16 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
17 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
18 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.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"
24 #define DEBUG_TYPE "aarch64-prelegalizer-combiner"
27 using namespace MIPatternMatch
;
30 class AArch64PreLegalizerCombinerInfo
: public CombinerInfo
{
34 AArch64PreLegalizerCombinerInfo(bool EnableOpt
, bool OptSize
, bool MinSize
,
36 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
37 /*LegalizerInfo*/ nullptr, EnableOpt
, OptSize
, MinSize
),
39 virtual bool combine(GISelChangeObserver
&Observer
, MachineInstr
&MI
,
40 MachineIRBuilder
&B
) const override
;
43 bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver
&Observer
,
45 MachineIRBuilder
&B
) const {
46 CombinerHelper
Helper(Observer
, B
, KB
);
48 switch (MI
.getOpcode()) {
51 case TargetOpcode::COPY
:
52 return Helper
.tryCombineCopy(MI
);
53 case TargetOpcode::G_BR
:
54 return Helper
.tryCombineBr(MI
);
55 case TargetOpcode::G_LOAD
:
56 case TargetOpcode::G_SEXTLOAD
:
57 case TargetOpcode::G_ZEXTLOAD
:
58 return Helper
.tryCombineExtendingLoads(MI
);
59 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS
:
60 switch (MI
.getIntrinsicID()) {
61 case Intrinsic::memcpy
:
62 case Intrinsic::memmove
:
63 case Intrinsic::memset
: {
64 // If we're at -O0 set a maxlen of 32 to inline, otherwise let the other
66 unsigned MaxLen
= EnableOpt
? 0 : 32;
67 // Try to inline memcpy type calls if optimizations are enabled.
68 return (!EnableOptSize
) ? Helper
.tryCombineMemCpyFamily(MI
, MaxLen
)
82 class AArch64PreLegalizerCombiner
: public MachineFunctionPass
{
86 AArch64PreLegalizerCombiner();
88 StringRef
getPassName() const override
{ return "AArch64PreLegalizerCombiner"; }
90 bool runOnMachineFunction(MachineFunction
&MF
) override
;
92 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
96 void AArch64PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage
&AU
) const {
97 AU
.addRequired
<TargetPassConfig
>();
99 getSelectionDAGFallbackAnalysisUsage(AU
);
100 AU
.addRequired
<GISelKnownBitsAnalysis
>();
101 AU
.addPreserved
<GISelKnownBitsAnalysis
>();
102 MachineFunctionPass::getAnalysisUsage(AU
);
105 AArch64PreLegalizerCombiner::AArch64PreLegalizerCombiner() : MachineFunctionPass(ID
) {
106 initializeAArch64PreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
109 bool AArch64PreLegalizerCombiner::runOnMachineFunction(MachineFunction
&MF
) {
110 if (MF
.getProperties().hasProperty(
111 MachineFunctionProperties::Property::FailedISel
))
113 auto *TPC
= &getAnalysis
<TargetPassConfig
>();
114 const Function
&F
= MF
.getFunction();
116 MF
.getTarget().getOptLevel() != CodeGenOpt::None
&& !skipFunction(F
);
117 GISelKnownBits
*KB
= &getAnalysis
<GISelKnownBitsAnalysis
>().get(MF
);
118 AArch64PreLegalizerCombinerInfo
PCInfo(EnableOpt
, F
.hasOptSize(),
120 Combiner
C(PCInfo
, TPC
);
121 return C
.combineMachineInstrs(MF
, /*CSEInfo*/ nullptr);
124 char AArch64PreLegalizerCombiner::ID
= 0;
125 INITIALIZE_PASS_BEGIN(AArch64PreLegalizerCombiner
, DEBUG_TYPE
,
126 "Combine AArch64 machine instrs before legalization",
128 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig
)
129 INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis
)
130 INITIALIZE_PASS_END(AArch64PreLegalizerCombiner
, DEBUG_TYPE
,
131 "Combine AArch64 machine instrs before legalization", false,
136 FunctionPass
*createAArch64PreLegalizeCombiner() {
137 return new AArch64PreLegalizerCombiner();
139 } // end namespace llvm