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"
22 #include "llvm/Support/Debug.h"
23 
24 #define DEBUG_TYPE "aarch64-prelegalizer-combiner"
25 
26 using namespace llvm;
27 using namespace MIPatternMatch;
28 
29 namespace {
30 class AArch64PreLegalizerCombinerInfo : public CombinerInfo {
31  GISelKnownBits *KB;
32 
33 public:
34  AArch64PreLegalizerCombinerInfo(bool EnableOpt, bool OptSize, bool MinSize,
35  GISelKnownBits *KB)
36  : CombinerInfo(/*AllowIllegalOps*/ true, /*ShouldLegalizeIllegal*/ false,
37  /*LegalizerInfo*/ nullptr, EnableOpt, OptSize, MinSize),
38  KB(KB) {}
39  virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI,
40  MachineIRBuilder &B) const override;
41 };
42 
43 bool AArch64PreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
45  MachineIRBuilder &B) const {
46  CombinerHelper Helper(Observer, B, KB);
47 
48  switch (MI.getOpcode()) {
49  default:
50  return false;
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
65  // heuristics decide.
66  unsigned MaxLen = EnableOpt ? 0 : 32;
67  // Try to inline memcpy type calls if optimizations are enabled.
68  return (!EnableOptSize) ? Helper.tryCombineMemCpyFamily(MI, MaxLen)
69  : false;
70  }
71  default:
72  break;
73  }
74  }
75 
76  return false;
77 }
78 
79 // Pass boilerplate
80 // ================
81 
82 class AArch64PreLegalizerCombiner : public MachineFunctionPass {
83 public:
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 
96 void AArch64PreLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
98  AU.setPreservesCFG();
103 }
104 
105 AArch64PreLegalizerCombiner::AArch64PreLegalizerCombiner() : MachineFunctionPass(ID) {
107 }
108 
109 bool AArch64PreLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
110  if (MF.getProperties().hasProperty(
112  return false;
113  auto *TPC = &getAnalysis<TargetPassConfig>();
114  const Function &F = MF.getFunction();
115  bool EnableOpt =
116  MF.getTarget().getOptLevel() != CodeGenOpt::None && !skipFunction(F);
117  GISelKnownBits *KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
118  AArch64PreLegalizerCombinerInfo PCInfo(EnableOpt, F.hasOptSize(),
119  F.hasMinSize(), KB);
120  Combiner C(PCInfo, TPC);
121  return C.combineMachineInstrs(MF, /*CSEInfo*/ nullptr);
122 }
123 
125 INITIALIZE_PASS_BEGIN(AArch64PreLegalizerCombiner, DEBUG_TYPE,
126  "Combine AArch64 machine instrs before legalization",
127  false, false)
130 INITIALIZE_PASS_END(AArch64PreLegalizerCombiner, DEBUG_TYPE,
131  "Combine AArch64 machine instrs before legalization", false,
132  false)
133 
134 
135 namespace llvm {
137  return new AArch64PreLegalizerCombiner();
138 }
139 } // 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
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
FunctionPass * createAArch64PreLegalizeCombiner()
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