1*cfef1803SAmara Emerson //===-- CodeGenCommonISel.cpp ---------------------------------------------===//
2*cfef1803SAmara Emerson //
3*cfef1803SAmara Emerson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*cfef1803SAmara Emerson // See https://llvm.org/LICENSE.txt for license information.
5*cfef1803SAmara Emerson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*cfef1803SAmara Emerson //
7*cfef1803SAmara Emerson //===----------------------------------------------------------------------===//
8*cfef1803SAmara Emerson //
9*cfef1803SAmara Emerson // This file defines common utilies that are shared between SelectionDAG and
10*cfef1803SAmara Emerson // GlobalISel frameworks.
11*cfef1803SAmara Emerson //
12*cfef1803SAmara Emerson //===----------------------------------------------------------------------===//
13*cfef1803SAmara Emerson 
14*cfef1803SAmara Emerson #include "llvm/CodeGen/CodeGenCommonISel.h"
15*cfef1803SAmara Emerson #include "llvm/Analysis/BranchProbabilityInfo.h"
16*cfef1803SAmara Emerson #include "llvm/CodeGen/MachineBasicBlock.h"
17*cfef1803SAmara Emerson #include "llvm/CodeGen/MachineFunction.h"
18*cfef1803SAmara Emerson #include "llvm/CodeGen/TargetInstrInfo.h"
19*cfef1803SAmara Emerson #include "llvm/CodeGen/TargetOpcodes.h"
20*cfef1803SAmara Emerson 
21*cfef1803SAmara Emerson using namespace llvm;
22*cfef1803SAmara Emerson 
23*cfef1803SAmara Emerson /// Add a successor MBB to ParentMBB< creating a new MachineBB for BB if SuccMBB
24*cfef1803SAmara Emerson /// is 0.
25*cfef1803SAmara Emerson MachineBasicBlock *
26*cfef1803SAmara Emerson StackProtectorDescriptor::addSuccessorMBB(
27*cfef1803SAmara Emerson     const BasicBlock *BB, MachineBasicBlock *ParentMBB, bool IsLikely,
28*cfef1803SAmara Emerson     MachineBasicBlock *SuccMBB) {
29*cfef1803SAmara Emerson   // If SuccBB has not been created yet, create it.
30*cfef1803SAmara Emerson   if (!SuccMBB) {
31*cfef1803SAmara Emerson     MachineFunction *MF = ParentMBB->getParent();
32*cfef1803SAmara Emerson     MachineFunction::iterator BBI(ParentMBB);
33*cfef1803SAmara Emerson     SuccMBB = MF->CreateMachineBasicBlock(BB);
34*cfef1803SAmara Emerson     MF->insert(++BBI, SuccMBB);
35*cfef1803SAmara Emerson   }
36*cfef1803SAmara Emerson   // Add it as a successor of ParentMBB.
37*cfef1803SAmara Emerson   ParentMBB->addSuccessor(
38*cfef1803SAmara Emerson       SuccMBB, BranchProbabilityInfo::getBranchProbStackProtector(IsLikely));
39*cfef1803SAmara Emerson   return SuccMBB;
40*cfef1803SAmara Emerson }
41*cfef1803SAmara Emerson 
42*cfef1803SAmara Emerson /// Given that the input MI is before a partial terminator sequence TSeq, return
43*cfef1803SAmara Emerson /// true if M + TSeq also a partial terminator sequence.
44*cfef1803SAmara Emerson ///
45*cfef1803SAmara Emerson /// A Terminator sequence is a sequence of MachineInstrs which at this point in
46*cfef1803SAmara Emerson /// lowering copy vregs into physical registers, which are then passed into
47*cfef1803SAmara Emerson /// terminator instructors so we can satisfy ABI constraints. A partial
48*cfef1803SAmara Emerson /// terminator sequence is an improper subset of a terminator sequence (i.e. it
49*cfef1803SAmara Emerson /// may be the whole terminator sequence).
50*cfef1803SAmara Emerson static bool MIIsInTerminatorSequence(const MachineInstr &MI) {
51*cfef1803SAmara Emerson   // If we do not have a copy or an implicit def, we return true if and only if
52*cfef1803SAmara Emerson   // MI is a debug value.
53*cfef1803SAmara Emerson   if (!MI.isCopy() && !MI.isImplicitDef()) {
54*cfef1803SAmara Emerson     // Sometimes DBG_VALUE MI sneak in between the copies from the vregs to the
55*cfef1803SAmara Emerson     // physical registers if there is debug info associated with the terminator
56*cfef1803SAmara Emerson     // of our mbb. We want to include said debug info in our terminator
57*cfef1803SAmara Emerson     // sequence, so we return true in that case.
58*cfef1803SAmara Emerson     if (MI.isDebugInstr())
59*cfef1803SAmara Emerson       return true;
60*cfef1803SAmara Emerson 
61*cfef1803SAmara Emerson     // For GlobalISel, we may have extension instructions for arguments within
62*cfef1803SAmara Emerson     // copy sequences. Allow these.
63*cfef1803SAmara Emerson     switch (MI.getOpcode()) {
64*cfef1803SAmara Emerson     case TargetOpcode::G_TRUNC:
65*cfef1803SAmara Emerson     case TargetOpcode::G_ZEXT:
66*cfef1803SAmara Emerson     case TargetOpcode::G_ANYEXT:
67*cfef1803SAmara Emerson     case TargetOpcode::G_SEXT:
68*cfef1803SAmara Emerson     case TargetOpcode::G_MERGE_VALUES:
69*cfef1803SAmara Emerson     case TargetOpcode::G_UNMERGE_VALUES:
70*cfef1803SAmara Emerson     case TargetOpcode::G_CONCAT_VECTORS:
71*cfef1803SAmara Emerson     case TargetOpcode::G_BUILD_VECTOR:
72*cfef1803SAmara Emerson     case TargetOpcode::G_EXTRACT:
73*cfef1803SAmara Emerson       return true;
74*cfef1803SAmara Emerson     default:
75*cfef1803SAmara Emerson       return false;
76*cfef1803SAmara Emerson     }
77*cfef1803SAmara Emerson   }
78*cfef1803SAmara Emerson 
79*cfef1803SAmara Emerson   // We have left the terminator sequence if we are not doing one of the
80*cfef1803SAmara Emerson   // following:
81*cfef1803SAmara Emerson   //
82*cfef1803SAmara Emerson   // 1. Copying a vreg into a physical register.
83*cfef1803SAmara Emerson   // 2. Copying a vreg into a vreg.
84*cfef1803SAmara Emerson   // 3. Defining a register via an implicit def.
85*cfef1803SAmara Emerson 
86*cfef1803SAmara Emerson   // OPI should always be a register definition...
87*cfef1803SAmara Emerson   MachineInstr::const_mop_iterator OPI = MI.operands_begin();
88*cfef1803SAmara Emerson   if (!OPI->isReg() || !OPI->isDef())
89*cfef1803SAmara Emerson     return false;
90*cfef1803SAmara Emerson 
91*cfef1803SAmara Emerson   // Defining any register via an implicit def is always ok.
92*cfef1803SAmara Emerson   if (MI.isImplicitDef())
93*cfef1803SAmara Emerson     return true;
94*cfef1803SAmara Emerson 
95*cfef1803SAmara Emerson   // Grab the copy source...
96*cfef1803SAmara Emerson   MachineInstr::const_mop_iterator OPI2 = OPI;
97*cfef1803SAmara Emerson   ++OPI2;
98*cfef1803SAmara Emerson   assert(OPI2 != MI.operands_end()
99*cfef1803SAmara Emerson          && "Should have a copy implying we should have 2 arguments.");
100*cfef1803SAmara Emerson 
101*cfef1803SAmara Emerson   // Make sure that the copy dest is not a vreg when the copy source is a
102*cfef1803SAmara Emerson   // physical register.
103*cfef1803SAmara Emerson   if (!OPI2->isReg() || (!Register::isPhysicalRegister(OPI->getReg()) &&
104*cfef1803SAmara Emerson                          Register::isPhysicalRegister(OPI2->getReg())))
105*cfef1803SAmara Emerson     return false;
106*cfef1803SAmara Emerson 
107*cfef1803SAmara Emerson   return true;
108*cfef1803SAmara Emerson }
109*cfef1803SAmara Emerson 
110*cfef1803SAmara Emerson /// Find the split point at which to splice the end of BB into its success stack
111*cfef1803SAmara Emerson /// protector check machine basic block.
112*cfef1803SAmara Emerson ///
113*cfef1803SAmara Emerson /// On many platforms, due to ABI constraints, terminators, even before register
114*cfef1803SAmara Emerson /// allocation, use physical registers. This creates an issue for us since
115*cfef1803SAmara Emerson /// physical registers at this point can not travel across basic
116*cfef1803SAmara Emerson /// blocks. Luckily, selectiondag always moves physical registers into vregs
117*cfef1803SAmara Emerson /// when they enter functions and moves them through a sequence of copies back
118*cfef1803SAmara Emerson /// into the physical registers right before the terminator creating a
119*cfef1803SAmara Emerson /// ``Terminator Sequence''. This function is searching for the beginning of the
120*cfef1803SAmara Emerson /// terminator sequence so that we can ensure that we splice off not just the
121*cfef1803SAmara Emerson /// terminator, but additionally the copies that move the vregs into the
122*cfef1803SAmara Emerson /// physical registers.
123*cfef1803SAmara Emerson MachineBasicBlock::iterator
124*cfef1803SAmara Emerson llvm::findSplitPointForStackProtector(MachineBasicBlock *BB,
125*cfef1803SAmara Emerson                                       const TargetInstrInfo &TII) {
126*cfef1803SAmara Emerson   MachineBasicBlock::iterator SplitPoint = BB->getFirstTerminator();
127*cfef1803SAmara Emerson   if (SplitPoint == BB->begin())
128*cfef1803SAmara Emerson     return SplitPoint;
129*cfef1803SAmara Emerson 
130*cfef1803SAmara Emerson   MachineBasicBlock::iterator Start = BB->begin();
131*cfef1803SAmara Emerson   MachineBasicBlock::iterator Previous = SplitPoint;
132*cfef1803SAmara Emerson   --Previous;
133*cfef1803SAmara Emerson 
134*cfef1803SAmara Emerson   if (TII.isTailCall(*SplitPoint) &&
135*cfef1803SAmara Emerson       Previous->getOpcode() == TII.getCallFrameDestroyOpcode()) {
136*cfef1803SAmara Emerson     // Call frames cannot be nested, so if this frame is describing the tail
137*cfef1803SAmara Emerson     // call itself, then we must insert before the sequence even starts. For
138*cfef1803SAmara Emerson     // example:
139*cfef1803SAmara Emerson     //     <split point>
140*cfef1803SAmara Emerson     //     ADJCALLSTACKDOWN ...
141*cfef1803SAmara Emerson     //     <Moves>
142*cfef1803SAmara Emerson     //     ADJCALLSTACKUP ...
143*cfef1803SAmara Emerson     //     TAILJMP somewhere
144*cfef1803SAmara Emerson     // On the other hand, it could be an unrelated call in which case this tail
145*cfef1803SAmara Emerson     // call has to register moves of its own and should be the split point. For
146*cfef1803SAmara Emerson     // example:
147*cfef1803SAmara Emerson     //     ADJCALLSTACKDOWN
148*cfef1803SAmara Emerson     //     CALL something_else
149*cfef1803SAmara Emerson     //     ADJCALLSTACKUP
150*cfef1803SAmara Emerson     //     <split point>
151*cfef1803SAmara Emerson     //     TAILJMP somewhere
152*cfef1803SAmara Emerson     do {
153*cfef1803SAmara Emerson       --Previous;
154*cfef1803SAmara Emerson       if (Previous->isCall())
155*cfef1803SAmara Emerson         return SplitPoint;
156*cfef1803SAmara Emerson     } while(Previous->getOpcode() != TII.getCallFrameSetupOpcode());
157*cfef1803SAmara Emerson 
158*cfef1803SAmara Emerson     return Previous;
159*cfef1803SAmara Emerson   }
160*cfef1803SAmara Emerson 
161*cfef1803SAmara Emerson   while (MIIsInTerminatorSequence(*Previous)) {
162*cfef1803SAmara Emerson     SplitPoint = Previous;
163*cfef1803SAmara Emerson     if (Previous == Start)
164*cfef1803SAmara Emerson       break;
165*cfef1803SAmara Emerson     --Previous;
166*cfef1803SAmara Emerson   }
167*cfef1803SAmara Emerson 
168*cfef1803SAmara Emerson   return SplitPoint;
169*cfef1803SAmara Emerson }