10b57cec5SDimitry Andric //===-- PHIEliminationUtils.cpp - Helper functions for PHI elimination ----===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "PHIEliminationUtils.h" 100b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 110b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 120b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 140b57cec5SDimitry Andric using namespace llvm; 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric // findCopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg 170b57cec5SDimitry Andric // when following the CFG edge to SuccMBB. This needs to be after any def of 180b57cec5SDimitry Andric // SrcReg, but before any subsequent point where control flow might jump out of 190b57cec5SDimitry Andric // the basic block. 200b57cec5SDimitry Andric MachineBasicBlock::iterator 210b57cec5SDimitry Andric llvm::findPHICopyInsertPoint(MachineBasicBlock* MBB, MachineBasicBlock* SuccMBB, 220b57cec5SDimitry Andric unsigned SrcReg) { 230b57cec5SDimitry Andric // Handle the trivial case trivially. 240b57cec5SDimitry Andric if (MBB->empty()) 250b57cec5SDimitry Andric return MBB->begin(); 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric // Usually, we just want to insert the copy before the first terminator 280b57cec5SDimitry Andric // instruction. However, for the edge going to a landing pad, we must insert 29*5ffd83dbSDimitry Andric // the copy before the call/invoke instruction. Similarly for an INLINEASM_BR 30*5ffd83dbSDimitry Andric // going to an indirect target. 31*5ffd83dbSDimitry Andric if (!SuccMBB->isEHPad() && !SuccMBB->isInlineAsmBrIndirectTarget()) 320b57cec5SDimitry Andric return MBB->getFirstTerminator(); 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric // Discover any defs/uses in this basic block. 350b57cec5SDimitry Andric SmallPtrSet<MachineInstr*, 8> DefUsesInMBB; 360b57cec5SDimitry Andric MachineRegisterInfo& MRI = MBB->getParent()->getRegInfo(); 370b57cec5SDimitry Andric for (MachineInstr &RI : MRI.reg_instructions(SrcReg)) { 380b57cec5SDimitry Andric if (RI.getParent() == MBB) 390b57cec5SDimitry Andric DefUsesInMBB.insert(&RI); 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric MachineBasicBlock::iterator InsertPoint; 430b57cec5SDimitry Andric if (DefUsesInMBB.empty()) { 440b57cec5SDimitry Andric // No defs. Insert the copy at the start of the basic block. 450b57cec5SDimitry Andric InsertPoint = MBB->begin(); 460b57cec5SDimitry Andric } else if (DefUsesInMBB.size() == 1) { 470b57cec5SDimitry Andric // Insert the copy immediately after the def/use. 480b57cec5SDimitry Andric InsertPoint = *DefUsesInMBB.begin(); 490b57cec5SDimitry Andric ++InsertPoint; 500b57cec5SDimitry Andric } else { 510b57cec5SDimitry Andric // Insert the copy immediately after the last def/use. 520b57cec5SDimitry Andric InsertPoint = MBB->end(); 530b57cec5SDimitry Andric while (!DefUsesInMBB.count(&*--InsertPoint)) {} 540b57cec5SDimitry Andric ++InsertPoint; 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric // Make sure the copy goes after any phi nodes but before 580b57cec5SDimitry Andric // any debug nodes. 590b57cec5SDimitry Andric return MBB->SkipPHIsAndLabels(InsertPoint); 600b57cec5SDimitry Andric } 61