xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64PostCoalescerPass.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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