LLVM  10.0.0svn
AArch64PreLegalizerCombiner.cpp
Go to the documentation of this file.
1 //=== lib/CodeGen/GlobalISel/AArch64PreLegalizerCombiner.cpp --------------===//
2 //
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
6 //
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"
23 #include "llvm/Support/Debug.h"
24 
25 #define DEBUG_TYPE "aarch64-prelegalizer-combiner"
26 
27 using namespace llvm;
28 using namespace MIPatternMatch;
29 
30 namespace {
31 class AArch64PreLegalizerCombinerInfo : public CombinerInfo {
32  GISelKnownBits *KB;
34 
35 public:
36  AArch64PreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
38  : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
39  /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize),
40  KB(KB), MDT(MDT) {}
41  virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
42  MachineIRBuilder &B) const override;
43 };
44 
45 bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
47  MachineIRBuilder &B) const {
48  CombinerHelper Helper(Observer, B, KB, MDT);
49 
50  switch (MI.getOpcode()) {
51  default:
52  return false;
53  case TargetOpcode::COPY:
54  return Helper.tryCombineCopy(MI);
55  case TargetOpcode::G_BR:
56  return Helper.tryCombineBr(MI);
57  case TargetOpcode::G_LOAD:
58  case TargetOpcode::G_SEXTLOAD:
59  case TargetOpcode::G_ZEXTLOAD: {
60  bool Changed = false;
61  Changed |= Helper.tryCombineExtendingLoads(MI);
62  Changed |= Helper.tryCombineIndexedLoadStore(MI);
63  return Changed;
64  }
65  case TargetOpcode::G_STORE:
66  return Helper.tryCombineIndexedLoadStore(MI);
67  case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
68  switch (MI.getIntrinsicID()) {
69  case Intrinsic::memcpy:
70  case Intrinsic::memmove:
71  case Intrinsic::memset: {
72  // If we're at -O0 set a maxlen of 32 to inline, otherwise let the other
73  // heuristics decide.
74  unsigned MaxLen = EnableOpt ? 0 : 32;
75  // Try to inline memcpy type calls if optimizations are enabled.
76  return (!EnableOptSize) ? Helper.tryCombineMemCpyFamily(MI, MaxLen)
77  : false;
78  }
79  default:
80  break;
81  }
82  }
83 
84  return false;
85 }
86 
87 // Pass boilerplate
88 // ================
89 
90 class AArch64PreLegalizerCombiner : public MachineFunctionPass {
91 public:
92  static char ID;
93 
94  AArch64PreLegalizerCombiner(bool IsOptNone = false);
95 
96  StringRef getPassName() const override { return "AArch64PreLegalizerCombiner"; }
97 
98  bool runOnMachineFunction(MachineFunction &MF) override;
99 
100  void getAnalysisUsage(AnalysisUsage &AU) const override;
101 private:
102  bool IsOptNone;
103 };
104 }
105 
106 void AArch64PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
108  AU.setPreservesCFG();
112  if (!IsOptNone) {
115  }
117 }
118 
119 AArch64PreLegalizerCombiner::AArch64PreLegalizerCombiner(bool IsOptNone)
120  : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
122 }
123 
124 bool AArch64PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
125  if (MF.getProperties().hasProperty(
127  return false;
128  auto *TPC = &getAnalysis<TargetPassConfig>();
129  const Function &F = MF.getFunction();
130  bool EnableOpt =
131  MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
132  GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
133  MachineDominatorTree *MDT =
134  IsOptNone ? nullptr : &getAnalysis<MachineDominatorTree>();
135  AArch64PreLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
136  F.hasMinSize(), KB, MDT);
137  Combiner C(PCInfo, TPC);
138  return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
139 }
140 
142 INITIALIZE_PASS_BEGIN(AArch64PreLegalizerCombiner, DEBUG_TYPE,
143  "Combine AArch64 machine instrs before legalization",
144  false, false)
147 INITIALIZE_PASS_END(AArch64PreLegalizerCombiner, DEBUG_TYPE,
148  "Combine AArch64 machine instrs before legalization", false,
149  false)
150 
151 
152 namespace llvm {
154  return new AArch64PreLegalizerCombiner(IsOptNone);
155 }
156 } // end namespace llvm
uint64_t CallInst * C
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Combine AArch64 machine instrs before legalization
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
coro Split coroutine into a set of functions driving its state machine
Definition: CoroSplit.cpp:1597
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition: Utils.cpp:412
const MachineFunctionProperties & getProperties() const
Get the function properties.
F(f)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:50
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
bool tryCombineBr(MachineInstr &MI)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
Target-Independent Code Generator Pass Configuration Options.
#define DEBUG_TYPE
FunctionPass * createAArch64PreLegalizeCombiner(bool IsOptNone)
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis...
Abstract class that contains various methods for clients to notify about changes. ...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Helper class to build MachineInstr.
Represent the analysis usage information of a pass.
bool tryCombineExtendingLoads(MachineInstr &MI)
If MI is extend that consumes the result of a load, try to combine it.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
bool tryCombineCopy(MachineInstr &MI)
If MI is COPY, try to combine it.
INITIALIZE_PASS_BEGIN(AArch64PreLegalizerCombiner, DEBUG_TYPE, "Combine AArch64 machine instrs before legalization", false, false) INITIALIZE_PASS_END(AArch64PreLegalizerCombiner
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:301
const Function & getFunction() const
Return the LLVM function that this machine code represents.
void initializeAArch64PreLegalizerCombinerPass(PassRegistry &)
Representation of each machine instruction.
Definition: MachineInstr.h:64
bool tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen=0)
Optimize memcpy intrinsics et al, e.g.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool hasProperty(Property P) const
unsigned getIntrinsicID() const
Returns the Intrinsic::ID for this instruction.
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool tryCombineIndexedLoadStore(MachineInstr &MI)
Combine MI into a pre-indexed or post-indexed load/store operation if legal and the surrounding code ...