blob: 4e09db9884ffefba333065177b24b8b414a14e95 [file] [log] [blame]
Daniel Sanders34eac352018-10-03 02:21:30 +00001//=== lib/CodeGen/GlobalISel/AArch64PreLegalizerCombiner.cpp --------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Daniel Sanders34eac352018-10-03 02:21:30 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This pass does combining of machine instructions at the generic MI level,
10// before the legalizer.
11//
12//===----------------------------------------------------------------------===//
13
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"
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +000018#include "llvm/CodeGen/GlobalISel/GISelKnownBits.h"
Daniel Sanders34eac352018-10-03 02:21:30 +000019#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
26using namespace llvm;
27using namespace MIPatternMatch;
28
29namespace {
30class AArch64PreLegalizerCombinerInfo : public CombinerInfo {
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +000031 GISelKnownBits *KB;
32
Daniel Sanders34eac352018-10-03 02:21:30 +000033public:
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +000034 AArch64PreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
35 GISelKnownBits *KB)
Daniel Sanders34eac352018-10-03 02:21:30 +000036 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +000037 /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize),
38 KB(KB) {}
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000039 virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
Daniel Sanders34eac352018-10-03 02:21:30 +000040 MachineIRBuilder &B) const override;
41};
42
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000043bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
Daniel Sanders34eac352018-10-03 02:21:30 +000044 MachineInstr &MI,
45 MachineIRBuilder &B) const {
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +000046 CombinerHelper Helper(Observer, B, KB);
Daniel Sanders34eac352018-10-03 02:21:30 +000047
48 switch (MI.getOpcode()) {
49 default:
50 return false;
Amara Emerson93e58d22019-04-13 00:33:25 +000051 case TargetOpcode::COPY:
52 return Helper.tryCombineCopy(MI);
Amara Emerson6616e262019-07-09 16:05:59 +000053 case TargetOpcode::G_BR:
54 return Helper.tryCombineBr(MI);
Daniel Sanders34eac352018-10-03 02:21:30 +000055 case TargetOpcode::G_LOAD:
56 case TargetOpcode::G_SEXTLOAD:
57 case TargetOpcode::G_ZEXTLOAD:
58 return Helper.tryCombineExtendingLoads(MI);
Amara Emerson13af1ed2019-07-24 22:17:31 +000059 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
60 switch (MI.getIntrinsicID()) {
61 case Intrinsic::memcpy:
62 case Intrinsic::memmove:
63 case Intrinsic::memset: {
Amara Emerson85e5e282019-08-05 20:02:52 +000064 // If we're at -O0 set a maxlen of 32 to inline, otherwise let the other
65 // heuristics decide.
66 unsigned MaxLen = EnableOpt ? 0 : 32;
Amara Emerson13af1ed2019-07-24 22:17:31 +000067 // Try to inline memcpy type calls if optimizations are enabled.
Amara Emerson85e5e282019-08-05 20:02:52 +000068 return (!EnableOptSize) ? Helper.tryCombineMemCpyFamily(MI, MaxLen)
69 : false;
Amara Emerson13af1ed2019-07-24 22:17:31 +000070 }
71 default:
72 break;
73 }
Daniel Sanders34eac352018-10-03 02:21:30 +000074 }
75
76 return false;
77}
78
79// Pass boilerplate
80// ================
81
82class AArch64PreLegalizerCombiner : public MachineFunctionPass {
83public:
84 static char ID;
85
86 AArch64PreLegalizerCombiner();
87
88 StringRef getPassName() const override { return "AArch64PreLegalizerCombiner"; }
89
90 bool runOnMachineFunction(MachineFunction &MF) override;
91
92 void getAnalysisUsage(AnalysisUsage &AU) const override;
93};
94}
95
96void AArch64PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
97 AU.addRequired<TargetPassConfig>();
98 AU.setPreservesCFG();
99 getSelectionDAGFallbackAnalysisUsage(AU);
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +0000100 AU.addRequired<GISelKnownBitsAnalysis>();
101 AU.addPreserved<GISelKnownBitsAnalysis>();
Daniel Sanders34eac352018-10-03 02:21:30 +0000102 MachineFunctionPass::getAnalysisUsage(AU);
103}
104
105AArch64PreLegalizerCombiner::AArch64PreLegalizerCombiner() : MachineFunctionPass(ID) {
106 initializeAArch64PreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
107}
108
109bool AArch64PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
110 if (MF.getProperties().hasProperty(
111 MachineFunctionProperties::Property::FailedISel))
112 return false;
113 auto *TPC = &getAnalysis<TargetPassConfig>();
Amara Emerson13af1ed2019-07-24 22:17:31 +0000114 const Function &F = MF.getFunction();
115 bool EnableOpt =
116 MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +0000117 GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
Amara Emerson13af1ed2019-07-24 22:17:31 +0000118 AArch64PreLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +0000119 F.hasMinSize(), KB);
Daniel Sanders34eac352018-10-03 02:21:30 +0000120 Combiner C(PCInfo, TPC);
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000121 return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
Daniel Sanders34eac352018-10-03 02:21:30 +0000122}
123
124char AArch64PreLegalizerCombiner::ID = 0;
125INITIALIZE_PASS_BEGIN(AArch64PreLegalizerCombiner, DEBUG_TYPE,
126 "Combine AArch64 machine instrs before legalization",
127 false, false)
128INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
Aditya Nandakumarc8ac0292019-08-06 17:18:29 +0000129INITIALIZE_PASS_DEPENDENCY(GISelKnownBitsAnalysis)
Daniel Sanders34eac352018-10-03 02:21:30 +0000130INITIALIZE_PASS_END(AArch64PreLegalizerCombiner, DEBUG_TYPE,
131 "Combine AArch64 machine instrs before legalization", false,
132 false)
133
134
135namespace llvm {
136FunctionPass *createAArch64PreLegalizeCombiner() {
137 return new AArch64PreLegalizerCombiner();
138}
139} // end namespace llvm