LLVM 23.0.0git
AArch64PostCoalescerPass.cpp
Go to the documentation of this file.
1//===- AArch64PostCoalescerPass.cpp - AArch64 Post Coalescer pass ---------===//
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#include "AArch64.h"
14#include "llvm/CodeGen/Passes.h"
16
17using namespace llvm;
18
19#define DEBUG_TYPE "aarch64-post-coalescer"
20
21namespace {
22
23/// Expands FORM_TRANSPOSED_REG_TUPLE_{X2|X4}_PSEUDO instructions into copy
24/// sequences. Note: This expansion occurs immediately before greedy regalloc
25/// and after the coalescer and pre-RA scheduler.
26///
27/// Example:
28///
29/// %v2:zpr2 = FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO %v0.zsub0, %v1.zsub0
30///
31/// Expands to:
32///
33/// undef %v2.zsub0:zpr2 = COPY_INTO_TRANSPOSED_TUPLE %v0.zsub0, 2
34/// %v2.zsub1:zpr2 = COPY_INTO_TRANSPOSED_TUPLE %v1.zsub0, 2
35static bool expandFormTransposedRegTuple(MachineBasicBlock &MBB,
37 const TargetInstrInfo *TII =
38 MBB.getParent()->getSubtarget<AArch64Subtarget>().getInstrInfo();
39 unsigned TupleSize =
40 MI.getOpcode() == AArch64::FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO ? 2 : 4;
41
42 DebugLoc DL = MI.getDebugLoc();
43 Register TupleReg = MI.getOperand(0).getReg();
44 SmallVector<Register, 5> OrigRegs{TupleReg};
45 MachineBasicBlock::iterator FirstCopyMBBI;
46
47 for (unsigned I = 0; I < TupleSize; ++I) {
48 MachineOperand &SrcOp = MI.getOperand(I + 1);
49 OrigRegs.push_back(SrcOp.getReg());
50
51 // Ensure that if operand is killed, the kill flag is placed on the final
52 // copy for that operand.
53 if (SrcOp.isKill()) {
54 for (unsigned J = I + 2; J < MI.getNumOperands(); ++J) {
55 MachineOperand &LaterOp = MI.getOperand(J);
56 if (LaterOp.getReg() == SrcOp.getReg()) {
57 LaterOp.setIsKill();
58 SrcOp.setIsKill(false);
59 }
60 }
61 }
62
63 RegState DefState = I == 0 ? RegState::Undef : RegState::NoFlags;
64 MachineInstr *CopyMI =
65 BuildMI(MBB, MI, DL, TII->get(AArch64::COPY_INTO_TRANSPOSED_TUPLE))
66 .addDef(TupleReg, DefState, AArch64::zsub0 + I)
67 .add(SrcOp)
68 .addImm(TupleSize);
69
70 if (I == 0)
71 FirstCopyMBBI = CopyMI;
72 }
73
74 MachineBasicBlock::iterator EndMBBI = std::next(MI.getIterator());
75 if (LIS)
77 MI.eraseFromParent();
78
79 if (LIS)
80 LIS->repairIntervalsInRange(&MBB, FirstCopyMBBI, EndMBBI, OrigRegs);
81 return true;
82}
83
84bool runAArch64PostCoalescer(MachineFunction &MF, LiveIntervals *LIS) {
86 if (!FuncInfo->hasStreamingModeChanges() &&
88 return false;
89
91 bool Changed = false;
92
93 for (MachineBasicBlock &MBB : MF) {
95 switch (MI.getOpcode()) {
96 default:
97 break;
98 case AArch64::FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO:
99 case AArch64::FORM_TRANSPOSED_REG_TUPLE_X4_PSEUDO:
100 Changed |= expandFormTransposedRegTuple(MBB, MI, LIS);
101 break;
102 case AArch64::COALESCER_BARRIER_FPR16:
103 case AArch64::COALESCER_BARRIER_FPR32:
104 case AArch64::COALESCER_BARRIER_FPR64:
105 case AArch64::COALESCER_BARRIER_FPR128: {
106 Register Src = MI.getOperand(1).getReg();
107 Register Dst = MI.getOperand(0).getReg();
108 if (Src != Dst)
109 MRI.replaceRegWith(Dst, Src);
110
111 if (MI.getOperand(1).isUndef())
112 for (MachineOperand &MO : MRI.use_operands(Dst))
113 MO.setIsUndef();
114
115 // MI must be erased from the basic block before recalculating the live
116 // interval.
117 if (LIS)
119 MI.eraseFromParent();
120
121 if (LIS) {
122 LIS->removeInterval(Src);
124 }
125
126 Changed = true;
127 break;
128 }
129 }
130 }
131 }
132
133 return Changed;
134}
135
136struct AArch64PostCoalescerLegacy : public MachineFunctionPass {
137 static char ID;
138
139 AArch64PostCoalescerLegacy() : MachineFunctionPass(ID) {}
140
141 bool runOnMachineFunction(MachineFunction &MF) override;
142
143 StringRef getPassName() const override {
144 return "AArch64 Post Coalescer pass";
145 }
146
147 void getAnalysisUsage(AnalysisUsage &AU) const override {
148 AU.setPreservesCFG();
153 }
154};
155
156char AArch64PostCoalescerLegacy::ID = 0;
157
158} // end anonymous namespace
159
160INITIALIZE_PASS_BEGIN(AArch64PostCoalescerLegacy, "aarch64-post-coalescer",
161 "AArch64 Post Coalescer Pass", false, false)
163INITIALIZE_PASS_END(AArch64PostCoalescerLegacy, "aarch64-post-coalescer",
164 "AArch64 Post Coalescer Pass", false, false)
165
166bool AArch64PostCoalescerLegacy::runOnMachineFunction(MachineFunction &MF) {
167 if (skipFunction(MF.getFunction()))
168 return false;
169
170 auto *LISWrapper = getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
171 auto *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
172 return runAArch64PostCoalescer(MF, LIS);
173}
174
178 auto *LIS = MFAM.getCachedResult<LiveIntervalsAnalysis>(MF);
179 const bool Changed = runAArch64PostCoalescer(MF, LIS);
180 if (!Changed)
181 return PreservedAnalyses::all();
186 return PA;
187}
188
190 return new AArch64PostCoalescerLegacy();
191}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool isStreaming() const
Returns true if the function has a streaming body.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
A debug info location.
Definition DebugLoc.h:126
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
LLVM_ABI void repairIntervalsInRange(MachineBasicBlock *MBB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, ArrayRef< Register > OrigRegs)
Update live intervals for instructions in a range of iterators.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
void removeInterval(Register Reg)
Interval removal.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
iterator_range< use_iterator > use_operands(Register Reg) const
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
Wrapper class representing virtual and physical registers.
Definition Register.h:20
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Register getReg() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TargetInstrInfo - Interface to description of machine instruction set.
Changed
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RegState
Flags to represent properties of register accesses.
@ Undef
Value of the register doesn't matter.
@ NoFlags
No Specific Flags.
FunctionPass * createAArch64PostCoalescerPass()
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.