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 25*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 34*0fca6ea1SDimitry Andric StringRef getPassName() const override { 35*0fca6ea1SDimitry Andric return "AArch64 Post Coalescer pass"; 36*0fca6ea1SDimitry Andric } 37*0fca6ea1SDimitry Andric 38*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) 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 99*0fca6ea1SDimitry Andric FunctionPass *llvm::createAArch64PostCoalescerPass() { 100*0fca6ea1SDimitry Andric return new AArch64PostCoalescer(); 101*0fca6ea1SDimitry Andric } 102