blob: 835fcf09f0ae5d757a971600e53b0e689b0128c5 [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"
18#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
19#include "llvm/CodeGen/MachineFunctionPass.h"
20#include "llvm/CodeGen/TargetPassConfig.h"
21#include "llvm/Support/Debug.h"
22
23#define DEBUG_TYPE "aarch64-prelegalizer-combiner"
24
25using namespace llvm;
26using namespace MIPatternMatch;
27
28namespace {
29class AArch64PreLegalizerCombinerInfo : public CombinerInfo {
30public:
Amara Emerson13af1ed2019-07-24 22:17:31 +000031 AArch64PreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize)
Daniel Sanders34eac352018-10-03 02:21:30 +000032 : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
Amara Emerson13af1ed2019-07-24 22:17:31 +000033 /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize) {}
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000034 virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
Daniel Sanders34eac352018-10-03 02:21:30 +000035 MachineIRBuilder &B) const override;
36};
37
Aditya Nandakumarf75d4f32018-12-05 20:14:52 +000038bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
Daniel Sanders34eac352018-10-03 02:21:30 +000039 MachineInstr &MI,
40 MachineIRBuilder &B) const {
41 CombinerHelper Helper(Observer, B);
42
43 switch (MI.getOpcode()) {
44 default:
45 return false;
Amara Emerson93e58d22019-04-13 00:33:25 +000046 case TargetOpcode::COPY:
47 return Helper.tryCombineCopy(MI);
Amara Emerson6616e262019-07-09 16:05:59 +000048 case TargetOpcode::G_BR:
49 return Helper.tryCombineBr(MI);
Daniel Sanders34eac352018-10-03 02:21:30 +000050 case TargetOpcode::G_LOAD:
51 case TargetOpcode::G_SEXTLOAD:
52 case TargetOpcode::G_ZEXTLOAD:
53 return Helper.tryCombineExtendingLoads(MI);
Amara Emerson13af1ed2019-07-24 22:17:31 +000054 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
55 switch (MI.getIntrinsicID()) {
56 case Intrinsic::memcpy:
57 case Intrinsic::memmove:
58 case Intrinsic::memset: {
Amara Emerson85e5e282019-08-05 20:02:52 +000059 // If we're at -O0 set a maxlen of 32 to inline, otherwise let the other
60 // heuristics decide.
61 unsigned MaxLen = EnableOpt ? 0 : 32;
Amara Emerson13af1ed2019-07-24 22:17:31 +000062 // Try to inline memcpy type calls if optimizations are enabled.
Amara Emerson85e5e282019-08-05 20:02:52 +000063 return (!EnableOptSize) ? Helper.tryCombineMemCpyFamily(MI, MaxLen)
64 : false;
Amara Emerson13af1ed2019-07-24 22:17:31 +000065 }
66 default:
67 break;
68 }
Daniel Sanders34eac352018-10-03 02:21:30 +000069 }
70
71 return false;
72}
73
74// Pass boilerplate
75// ================
76
77class AArch64PreLegalizerCombiner : public MachineFunctionPass {
78public:
79 static char ID;
80
81 AArch64PreLegalizerCombiner();
82
83 StringRef getPassName() const override { return "AArch64PreLegalizerCombiner"; }
84
85 bool runOnMachineFunction(MachineFunction &MF) override;
86
87 void getAnalysisUsage(AnalysisUsage &AU) const override;
88};
89}
90
91void AArch64PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
92 AU.addRequired<TargetPassConfig>();
93 AU.setPreservesCFG();
94 getSelectionDAGFallbackAnalysisUsage(AU);
95 MachineFunctionPass::getAnalysisUsage(AU);
96}
97
98AArch64PreLegalizerCombiner::AArch64PreLegalizerCombiner() : MachineFunctionPass(ID) {
99 initializeAArch64PreLegalizerCombinerPass(*PassRegistry::getPassRegistry());
100}
101
102bool AArch64PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
103 if (MF.getProperties().hasProperty(
104 MachineFunctionProperties::Property::FailedISel))
105 return false;
106 auto *TPC = &getAnalysis<TargetPassConfig>();
Amara Emerson13af1ed2019-07-24 22:17:31 +0000107 const Function &F = MF.getFunction();
108 bool EnableOpt =
109 MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
110 AArch64PreLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
111 F.hasMinSize());
Daniel Sanders34eac352018-10-03 02:21:30 +0000112 Combiner C(PCInfo, TPC);
Aditya Nandakumar500e3ea2019-01-16 00:40:37 +0000113 return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
Daniel Sanders34eac352018-10-03 02:21:30 +0000114}
115
116char AArch64PreLegalizerCombiner::ID = 0;
117INITIALIZE_PASS_BEGIN(AArch64PreLegalizerCombiner, DEBUG_TYPE,
118 "Combine AArch64 machine instrs before legalization",
119 false, false)
120INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
121INITIALIZE_PASS_END(AArch64PreLegalizerCombiner, DEBUG_TYPE,
122 "Combine AArch64 machine instrs before legalization", false,
123 false)
124
125
126namespace llvm {
127FunctionPass *createAArch64PreLegalizeCombiner() {
128 return new AArch64PreLegalizerCombiner();
129}
130} // end namespace llvm