xref: /aosp_15_r20/external/llvm/lib/CodeGen/PHIEliminationUtils.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- PHIEliminationUtils.cpp - Helper functions for PHI elimination ----===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "PHIEliminationUtils.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
15*9880d681SAndroid Build Coastguard Worker using namespace llvm;
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker // findCopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg
18*9880d681SAndroid Build Coastguard Worker // when following the CFG edge to SuccMBB. This needs to be after any def of
19*9880d681SAndroid Build Coastguard Worker // SrcReg, but before any subsequent point where control flow might jump out of
20*9880d681SAndroid Build Coastguard Worker // the basic block.
21*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator
findPHICopyInsertPoint(MachineBasicBlock * MBB,MachineBasicBlock * SuccMBB,unsigned SrcReg)22*9880d681SAndroid Build Coastguard Worker llvm::findPHICopyInsertPoint(MachineBasicBlock* MBB, MachineBasicBlock* SuccMBB,
23*9880d681SAndroid Build Coastguard Worker                              unsigned SrcReg) {
24*9880d681SAndroid Build Coastguard Worker   // Handle the trivial case trivially.
25*9880d681SAndroid Build Coastguard Worker   if (MBB->empty())
26*9880d681SAndroid Build Coastguard Worker     return MBB->begin();
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker   // Usually, we just want to insert the copy before the first terminator
29*9880d681SAndroid Build Coastguard Worker   // instruction. However, for the edge going to a landing pad, we must insert
30*9880d681SAndroid Build Coastguard Worker   // the copy before the call/invoke instruction.
31*9880d681SAndroid Build Coastguard Worker   if (!SuccMBB->isEHPad())
32*9880d681SAndroid Build Coastguard Worker     return MBB->getFirstTerminator();
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker   // Discover any defs/uses in this basic block.
35*9880d681SAndroid Build Coastguard Worker   SmallPtrSet<MachineInstr*, 8> DefUsesInMBB;
36*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo& MRI = MBB->getParent()->getRegInfo();
37*9880d681SAndroid Build Coastguard Worker   for (MachineInstr &RI : MRI.reg_instructions(SrcReg)) {
38*9880d681SAndroid Build Coastguard Worker     if (RI.getParent() == MBB)
39*9880d681SAndroid Build Coastguard Worker       DefUsesInMBB.insert(&RI);
40*9880d681SAndroid Build Coastguard Worker   }
41*9880d681SAndroid Build Coastguard Worker 
42*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator InsertPoint;
43*9880d681SAndroid Build Coastguard Worker   if (DefUsesInMBB.empty()) {
44*9880d681SAndroid Build Coastguard Worker     // No defs.  Insert the copy at the start of the basic block.
45*9880d681SAndroid Build Coastguard Worker     InsertPoint = MBB->begin();
46*9880d681SAndroid Build Coastguard Worker   } else if (DefUsesInMBB.size() == 1) {
47*9880d681SAndroid Build Coastguard Worker     // Insert the copy immediately after the def/use.
48*9880d681SAndroid Build Coastguard Worker     InsertPoint = *DefUsesInMBB.begin();
49*9880d681SAndroid Build Coastguard Worker     ++InsertPoint;
50*9880d681SAndroid Build Coastguard Worker   } else {
51*9880d681SAndroid Build Coastguard Worker     // Insert the copy immediately after the last def/use.
52*9880d681SAndroid Build Coastguard Worker     InsertPoint = MBB->end();
53*9880d681SAndroid Build Coastguard Worker     while (!DefUsesInMBB.count(&*--InsertPoint)) {}
54*9880d681SAndroid Build Coastguard Worker     ++InsertPoint;
55*9880d681SAndroid Build Coastguard Worker   }
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker   // Make sure the copy goes after any phi nodes however.
58*9880d681SAndroid Build Coastguard Worker   return MBB->SkipPHIsAndLabels(InsertPoint);
59*9880d681SAndroid Build Coastguard Worker }
60