185 lines · cpp
1//===-- ExpandPostRAPseudos.cpp - Pseudo instruction expansion 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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines a pass that expands COPY and SUBREG_TO_REG pseudo10// instructions after register allocation.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/CodeGen/ExpandPostRAPseudos.h"15#include "llvm/CodeGen/MachineDominators.h"16#include "llvm/CodeGen/MachineFunctionPass.h"17#include "llvm/CodeGen/MachineInstr.h"18#include "llvm/CodeGen/MachineLoopInfo.h"19#include "llvm/CodeGen/Passes.h"20#include "llvm/CodeGen/TargetInstrInfo.h"21#include "llvm/CodeGen/TargetRegisterInfo.h"22#include "llvm/CodeGen/TargetSubtargetInfo.h"23#include "llvm/InitializePasses.h"24#include "llvm/Support/Debug.h"25#include "llvm/Support/raw_ostream.h"26 27using namespace llvm;28 29#define DEBUG_TYPE "postrapseudos"30 31namespace {32struct ExpandPostRA {33 bool run(MachineFunction &);34 35private:36 const TargetRegisterInfo *TRI = nullptr;37 const TargetInstrInfo *TII = nullptr;38 39 bool LowerSubregToReg(MachineInstr *MI);40};41 42struct ExpandPostRALegacy : public MachineFunctionPass {43 static char ID;44 ExpandPostRALegacy() : MachineFunctionPass(ID) {45 initializeExpandPostRALegacyPass(*PassRegistry::getPassRegistry());46 }47 48 void getAnalysisUsage(AnalysisUsage &AU) const override {49 AU.setPreservesCFG();50 AU.addPreservedID(MachineLoopInfoID);51 AU.addPreservedID(MachineDominatorsID);52 MachineFunctionPass::getAnalysisUsage(AU);53 }54 55 /// runOnMachineFunction - pass entry point56 bool runOnMachineFunction(MachineFunction &) override;57};58} // end anonymous namespace59 60PreservedAnalyses61ExpandPostRAPseudosPass::run(MachineFunction &MF,62 MachineFunctionAnalysisManager &MFAM) {63 if (!ExpandPostRA().run(MF))64 return PreservedAnalyses::all();65 66 return getMachineFunctionPassPreservedAnalyses()67 .preserveSet<CFGAnalyses>()68 .preserve<MachineLoopAnalysis>()69 .preserve<MachineDominatorTreeAnalysis>();70}71 72char ExpandPostRALegacy::ID = 0;73char &llvm::ExpandPostRAPseudosID = ExpandPostRALegacy::ID;74 75INITIALIZE_PASS(ExpandPostRALegacy, DEBUG_TYPE,76 "Post-RA pseudo instruction expansion pass", false, false)77 78bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) {79 MachineBasicBlock *MBB = MI->getParent();80 assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) &&81 MI->getOperand(1).isImm() &&82 (MI->getOperand(2).isReg() && MI->getOperand(2).isUse()) &&83 MI->getOperand(3).isImm() && "Invalid subreg_to_reg");84 85 Register DstReg = MI->getOperand(0).getReg();86 Register InsReg = MI->getOperand(2).getReg();87 assert(!MI->getOperand(2).getSubReg() && "SubIdx on physreg?");88 unsigned SubIdx = MI->getOperand(3).getImm();89 90 assert(SubIdx != 0 && "Invalid index for insert_subreg");91 Register DstSubReg = TRI->getSubReg(DstReg, SubIdx);92 93 assert(DstReg.isPhysical() &&94 "Insert destination must be in a physical register");95 assert(InsReg.isPhysical() &&96 "Inserted value must be in a physical register");97 98 LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI);99 100 if (MI->allDefsAreDead()) {101 MI->setDesc(TII->get(TargetOpcode::KILL));102 MI->removeOperand(3); // SubIdx103 MI->removeOperand(1); // Imm104 LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI);105 return true;106 }107 108 if (DstSubReg == InsReg) {109 // No need to insert an identity copy instruction.110 // Watch out for case like this:111 // %rax = SUBREG_TO_REG 0, killed %eax, 3112 // We must leave %rax live.113 if (DstReg != InsReg) {114 MI->setDesc(TII->get(TargetOpcode::KILL));115 MI->removeOperand(3); // SubIdx116 MI->removeOperand(1); // Imm117 LLVM_DEBUG(dbgs() << "subreg: replace by: " << *MI);118 return true;119 }120 LLVM_DEBUG(dbgs() << "subreg: eliminated!");121 } else {122 TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg,123 MI->getOperand(2).isKill());124 125 // Implicitly define DstReg for subsequent uses.126 MachineBasicBlock::iterator CopyMI = MI;127 --CopyMI;128 CopyMI->addRegisterDefined(DstReg);129 LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI);130 }131 132 LLVM_DEBUG(dbgs() << '\n');133 MBB->erase(MI);134 return true;135}136 137bool ExpandPostRALegacy::runOnMachineFunction(MachineFunction &MF) {138 return ExpandPostRA().run(MF);139}140 141/// runOnMachineFunction - Reduce subregister inserts and extracts to register142/// copies.143///144bool ExpandPostRA::run(MachineFunction &MF) {145 LLVM_DEBUG(dbgs() << "Machine Function\n"146 << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n"147 << "********** Function: " << MF.getName() << '\n');148 TRI = MF.getSubtarget().getRegisterInfo();149 TII = MF.getSubtarget().getInstrInfo();150 151 bool MadeChange = false;152 153 for (MachineBasicBlock &MBB : MF) {154 for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {155 // Only expand pseudos.156 if (!MI.isPseudo())157 continue;158 159 // Give targets a chance to expand even standard pseudos.160 if (TII->expandPostRAPseudo(MI)) {161 MadeChange = true;162 continue;163 }164 165 // Expand standard pseudos.166 switch (MI.getOpcode()) {167 case TargetOpcode::SUBREG_TO_REG:168 MadeChange |= LowerSubregToReg(&MI);169 break;170 case TargetOpcode::COPY:171 TII->lowerCopy(&MI, TRI);172 MadeChange = true;173 break;174 case TargetOpcode::DBG_VALUE:175 continue;176 case TargetOpcode::INSERT_SUBREG:177 case TargetOpcode::EXTRACT_SUBREG:178 llvm_unreachable("Sub-register pseudos should have been eliminated.");179 }180 }181 }182 183 return MadeChange;184}185