1*0fca6ea1SDimitry Andric //===- AArch64PostCoalescerPass.cpp - AArch64 Post Coalescer pass ---------===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
9*0fca6ea1SDimitry Andric
10*0fca6ea1SDimitry Andric #include "AArch64InstrInfo.h"
11*0fca6ea1SDimitry Andric #include "AArch64MachineFunctionInfo.h"
12*0fca6ea1SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
13*0fca6ea1SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
14*0fca6ea1SDimitry Andric #include "llvm/InitializePasses.h"
15*0fca6ea1SDimitry Andric
16*0fca6ea1SDimitry Andric using namespace llvm;
17*0fca6ea1SDimitry Andric
18*0fca6ea1SDimitry Andric #define DEBUG_TYPE "aarch64-post-coalescer-pass"
19*0fca6ea1SDimitry Andric
20*0fca6ea1SDimitry Andric namespace {
21*0fca6ea1SDimitry Andric
22*0fca6ea1SDimitry Andric struct AArch64PostCoalescer : public MachineFunctionPass {
23*0fca6ea1SDimitry Andric static char ID;
24*0fca6ea1SDimitry Andric
AArch64PostCoalescer__anon138d7d950111::AArch64PostCoalescer25*0fca6ea1SDimitry Andric AArch64PostCoalescer() : MachineFunctionPass(ID) {
26*0fca6ea1SDimitry Andric initializeAArch64PostCoalescerPass(*PassRegistry::getPassRegistry());
27*0fca6ea1SDimitry Andric }
28*0fca6ea1SDimitry Andric
29*0fca6ea1SDimitry Andric LiveIntervals *LIS;
30*0fca6ea1SDimitry Andric MachineRegisterInfo *MRI;
31*0fca6ea1SDimitry Andric
32*0fca6ea1SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override;
33*0fca6ea1SDimitry Andric
getPassName__anon138d7d950111::AArch64PostCoalescer34*0fca6ea1SDimitry Andric StringRef getPassName() const override {
35*0fca6ea1SDimitry Andric return "AArch64 Post Coalescer pass";
36*0fca6ea1SDimitry Andric }
37*0fca6ea1SDimitry Andric
getAnalysisUsage__anon138d7d950111::AArch64PostCoalescer38*0fca6ea1SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
39*0fca6ea1SDimitry Andric AU.setPreservesAll();
40*0fca6ea1SDimitry Andric AU.addRequired<LiveIntervalsWrapperPass>();
41*0fca6ea1SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
42*0fca6ea1SDimitry Andric }
43*0fca6ea1SDimitry Andric };
44*0fca6ea1SDimitry Andric
45*0fca6ea1SDimitry Andric char AArch64PostCoalescer::ID = 0;
46*0fca6ea1SDimitry Andric
47*0fca6ea1SDimitry Andric } // end anonymous namespace
48*0fca6ea1SDimitry Andric
49*0fca6ea1SDimitry Andric INITIALIZE_PASS_BEGIN(AArch64PostCoalescer, "aarch64-post-coalescer-pass",
50*0fca6ea1SDimitry Andric "AArch64 Post Coalescer Pass", false, false)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)51*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
52*0fca6ea1SDimitry Andric INITIALIZE_PASS_END(AArch64PostCoalescer, "aarch64-post-coalescer-pass",
53*0fca6ea1SDimitry Andric "AArch64 Post Coalescer Pass", false, false)
54*0fca6ea1SDimitry Andric
55*0fca6ea1SDimitry Andric bool AArch64PostCoalescer::runOnMachineFunction(MachineFunction &MF) {
56*0fca6ea1SDimitry Andric if (skipFunction(MF.getFunction()))
57*0fca6ea1SDimitry Andric return false;
58*0fca6ea1SDimitry Andric
59*0fca6ea1SDimitry Andric AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>();
60*0fca6ea1SDimitry Andric if (!FuncInfo->hasStreamingModeChanges())
61*0fca6ea1SDimitry Andric return false;
62*0fca6ea1SDimitry Andric
63*0fca6ea1SDimitry Andric MRI = &MF.getRegInfo();
64*0fca6ea1SDimitry Andric LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
65*0fca6ea1SDimitry Andric bool Changed = false;
66*0fca6ea1SDimitry Andric
67*0fca6ea1SDimitry Andric for (MachineBasicBlock &MBB : MF) {
68*0fca6ea1SDimitry Andric for (MachineInstr &MI : make_early_inc_range(MBB)) {
69*0fca6ea1SDimitry Andric switch (MI.getOpcode()) {
70*0fca6ea1SDimitry Andric default:
71*0fca6ea1SDimitry Andric break;
72*0fca6ea1SDimitry Andric case AArch64::COALESCER_BARRIER_FPR16:
73*0fca6ea1SDimitry Andric case AArch64::COALESCER_BARRIER_FPR32:
74*0fca6ea1SDimitry Andric case AArch64::COALESCER_BARRIER_FPR64:
75*0fca6ea1SDimitry Andric case AArch64::COALESCER_BARRIER_FPR128: {
76*0fca6ea1SDimitry Andric Register Src = MI.getOperand(1).getReg();
77*0fca6ea1SDimitry Andric Register Dst = MI.getOperand(0).getReg();
78*0fca6ea1SDimitry Andric if (Src != Dst)
79*0fca6ea1SDimitry Andric MRI->replaceRegWith(Dst, Src);
80*0fca6ea1SDimitry Andric
81*0fca6ea1SDimitry Andric // MI must be erased from the basic block before recalculating the live
82*0fca6ea1SDimitry Andric // interval.
83*0fca6ea1SDimitry Andric LIS->RemoveMachineInstrFromMaps(MI);
84*0fca6ea1SDimitry Andric MI.eraseFromParent();
85*0fca6ea1SDimitry Andric
86*0fca6ea1SDimitry Andric LIS->removeInterval(Src);
87*0fca6ea1SDimitry Andric LIS->createAndComputeVirtRegInterval(Src);
88*0fca6ea1SDimitry Andric
89*0fca6ea1SDimitry Andric Changed = true;
90*0fca6ea1SDimitry Andric break;
91*0fca6ea1SDimitry Andric }
92*0fca6ea1SDimitry Andric }
93*0fca6ea1SDimitry Andric }
94*0fca6ea1SDimitry Andric }
95*0fca6ea1SDimitry Andric
96*0fca6ea1SDimitry Andric return Changed;
97*0fca6ea1SDimitry Andric }
98*0fca6ea1SDimitry Andric
createAArch64PostCoalescerPass()99*0fca6ea1SDimitry Andric FunctionPass *llvm::createAArch64PostCoalescerPass() {
100*0fca6ea1SDimitry Andric return new AArch64PostCoalescer();
101*0fca6ea1SDimitry Andric }
102