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