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 }