1cfef1803SAmara Emerson //===-- CodeGenCommonISel.cpp ---------------------------------------------===// 2cfef1803SAmara Emerson // 3cfef1803SAmara Emerson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4cfef1803SAmara Emerson // See https://llvm.org/LICENSE.txt for license information. 5cfef1803SAmara Emerson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6cfef1803SAmara Emerson // 7cfef1803SAmara Emerson //===----------------------------------------------------------------------===// 8cfef1803SAmara Emerson // 9cfef1803SAmara Emerson // This file defines common utilies that are shared between SelectionDAG and 10cfef1803SAmara Emerson // GlobalISel frameworks. 11cfef1803SAmara Emerson // 12cfef1803SAmara Emerson //===----------------------------------------------------------------------===// 13cfef1803SAmara Emerson 14cfef1803SAmara Emerson #include "llvm/CodeGen/CodeGenCommonISel.h" 15cfef1803SAmara Emerson #include "llvm/Analysis/BranchProbabilityInfo.h" 16cfef1803SAmara Emerson #include "llvm/CodeGen/MachineBasicBlock.h" 17cfef1803SAmara Emerson #include "llvm/CodeGen/MachineFunction.h" 18cfef1803SAmara Emerson #include "llvm/CodeGen/TargetInstrInfo.h" 19cfef1803SAmara Emerson #include "llvm/CodeGen/TargetOpcodes.h" 20facb3ac3SVladislav Dzhidzhoev #include "llvm/IR/DebugInfoMetadata.h" 21facb3ac3SVladislav Dzhidzhoev 22facb3ac3SVladislav Dzhidzhoev #define DEBUG_TYPE "codegen-common" 23cfef1803SAmara Emerson 24cfef1803SAmara Emerson using namespace llvm; 25cfef1803SAmara Emerson 26cfef1803SAmara Emerson /// Add a successor MBB to ParentMBB< creating a new MachineBB for BB if SuccMBB 27cfef1803SAmara Emerson /// is 0. 28cfef1803SAmara Emerson MachineBasicBlock * 29cfef1803SAmara Emerson StackProtectorDescriptor::addSuccessorMBB( 30cfef1803SAmara Emerson const BasicBlock *BB, MachineBasicBlock *ParentMBB, bool IsLikely, 31cfef1803SAmara Emerson MachineBasicBlock *SuccMBB) { 32cfef1803SAmara Emerson // If SuccBB has not been created yet, create it. 33cfef1803SAmara Emerson if (!SuccMBB) { 34cfef1803SAmara Emerson MachineFunction *MF = ParentMBB->getParent(); 35cfef1803SAmara Emerson MachineFunction::iterator BBI(ParentMBB); 36cfef1803SAmara Emerson SuccMBB = MF->CreateMachineBasicBlock(BB); 37cfef1803SAmara Emerson MF->insert(++BBI, SuccMBB); 38cfef1803SAmara Emerson } 39cfef1803SAmara Emerson // Add it as a successor of ParentMBB. 40cfef1803SAmara Emerson ParentMBB->addSuccessor( 41cfef1803SAmara Emerson SuccMBB, BranchProbabilityInfo::getBranchProbStackProtector(IsLikely)); 42cfef1803SAmara Emerson return SuccMBB; 43cfef1803SAmara Emerson } 44cfef1803SAmara Emerson 45cfef1803SAmara Emerson /// Given that the input MI is before a partial terminator sequence TSeq, return 46cfef1803SAmara Emerson /// true if M + TSeq also a partial terminator sequence. 47cfef1803SAmara Emerson /// 48cfef1803SAmara Emerson /// A Terminator sequence is a sequence of MachineInstrs which at this point in 49cfef1803SAmara Emerson /// lowering copy vregs into physical registers, which are then passed into 50cfef1803SAmara Emerson /// terminator instructors so we can satisfy ABI constraints. A partial 51cfef1803SAmara Emerson /// terminator sequence is an improper subset of a terminator sequence (i.e. it 52cfef1803SAmara Emerson /// may be the whole terminator sequence). 53cfef1803SAmara Emerson static bool MIIsInTerminatorSequence(const MachineInstr &MI) { 54cfef1803SAmara Emerson // If we do not have a copy or an implicit def, we return true if and only if 55cfef1803SAmara Emerson // MI is a debug value. 56cfef1803SAmara Emerson if (!MI.isCopy() && !MI.isImplicitDef()) { 57cfef1803SAmara Emerson // Sometimes DBG_VALUE MI sneak in between the copies from the vregs to the 58cfef1803SAmara Emerson // physical registers if there is debug info associated with the terminator 59cfef1803SAmara Emerson // of our mbb. We want to include said debug info in our terminator 60cfef1803SAmara Emerson // sequence, so we return true in that case. 61cfef1803SAmara Emerson if (MI.isDebugInstr()) 62cfef1803SAmara Emerson return true; 63cfef1803SAmara Emerson 64cfef1803SAmara Emerson // For GlobalISel, we may have extension instructions for arguments within 65cfef1803SAmara Emerson // copy sequences. Allow these. 66cfef1803SAmara Emerson switch (MI.getOpcode()) { 67cfef1803SAmara Emerson case TargetOpcode::G_TRUNC: 68cfef1803SAmara Emerson case TargetOpcode::G_ZEXT: 69cfef1803SAmara Emerson case TargetOpcode::G_ANYEXT: 70cfef1803SAmara Emerson case TargetOpcode::G_SEXT: 71cfef1803SAmara Emerson case TargetOpcode::G_MERGE_VALUES: 72cfef1803SAmara Emerson case TargetOpcode::G_UNMERGE_VALUES: 73cfef1803SAmara Emerson case TargetOpcode::G_CONCAT_VECTORS: 74cfef1803SAmara Emerson case TargetOpcode::G_BUILD_VECTOR: 75cfef1803SAmara Emerson case TargetOpcode::G_EXTRACT: 76cfef1803SAmara Emerson return true; 77cfef1803SAmara Emerson default: 78cfef1803SAmara Emerson return false; 79cfef1803SAmara Emerson } 80cfef1803SAmara Emerson } 81cfef1803SAmara Emerson 82cfef1803SAmara Emerson // We have left the terminator sequence if we are not doing one of the 83cfef1803SAmara Emerson // following: 84cfef1803SAmara Emerson // 85cfef1803SAmara Emerson // 1. Copying a vreg into a physical register. 86cfef1803SAmara Emerson // 2. Copying a vreg into a vreg. 87cfef1803SAmara Emerson // 3. Defining a register via an implicit def. 88cfef1803SAmara Emerson 89cfef1803SAmara Emerson // OPI should always be a register definition... 90cfef1803SAmara Emerson MachineInstr::const_mop_iterator OPI = MI.operands_begin(); 91cfef1803SAmara Emerson if (!OPI->isReg() || !OPI->isDef()) 92cfef1803SAmara Emerson return false; 93cfef1803SAmara Emerson 94cfef1803SAmara Emerson // Defining any register via an implicit def is always ok. 95cfef1803SAmara Emerson if (MI.isImplicitDef()) 96cfef1803SAmara Emerson return true; 97cfef1803SAmara Emerson 98cfef1803SAmara Emerson // Grab the copy source... 99cfef1803SAmara Emerson MachineInstr::const_mop_iterator OPI2 = OPI; 100cfef1803SAmara Emerson ++OPI2; 101cfef1803SAmara Emerson assert(OPI2 != MI.operands_end() 102cfef1803SAmara Emerson && "Should have a copy implying we should have 2 arguments."); 103cfef1803SAmara Emerson 104cfef1803SAmara Emerson // Make sure that the copy dest is not a vreg when the copy source is a 105cfef1803SAmara Emerson // physical register. 106e72ca520SCraig Topper if (!OPI2->isReg() || 107e72ca520SCraig Topper (!OPI->getReg().isPhysical() && OPI2->getReg().isPhysical())) 108cfef1803SAmara Emerson return false; 109cfef1803SAmara Emerson 110cfef1803SAmara Emerson return true; 111cfef1803SAmara Emerson } 112cfef1803SAmara Emerson 113cfef1803SAmara Emerson /// Find the split point at which to splice the end of BB into its success stack 114cfef1803SAmara Emerson /// protector check machine basic block. 115cfef1803SAmara Emerson /// 116cfef1803SAmara Emerson /// On many platforms, due to ABI constraints, terminators, even before register 117cfef1803SAmara Emerson /// allocation, use physical registers. This creates an issue for us since 118cfef1803SAmara Emerson /// physical registers at this point can not travel across basic 119cfef1803SAmara Emerson /// blocks. Luckily, selectiondag always moves physical registers into vregs 120cfef1803SAmara Emerson /// when they enter functions and moves them through a sequence of copies back 121cfef1803SAmara Emerson /// into the physical registers right before the terminator creating a 122cfef1803SAmara Emerson /// ``Terminator Sequence''. This function is searching for the beginning of the 123cfef1803SAmara Emerson /// terminator sequence so that we can ensure that we splice off not just the 124cfef1803SAmara Emerson /// terminator, but additionally the copies that move the vregs into the 125cfef1803SAmara Emerson /// physical registers. 126cfef1803SAmara Emerson MachineBasicBlock::iterator 127cfef1803SAmara Emerson llvm::findSplitPointForStackProtector(MachineBasicBlock *BB, 128cfef1803SAmara Emerson const TargetInstrInfo &TII) { 129cfef1803SAmara Emerson MachineBasicBlock::iterator SplitPoint = BB->getFirstTerminator(); 130cfef1803SAmara Emerson if (SplitPoint == BB->begin()) 131cfef1803SAmara Emerson return SplitPoint; 132cfef1803SAmara Emerson 133cfef1803SAmara Emerson MachineBasicBlock::iterator Start = BB->begin(); 134cfef1803SAmara Emerson MachineBasicBlock::iterator Previous = SplitPoint; 135a87d3ba6STim Northover do { 136cfef1803SAmara Emerson --Previous; 137a87d3ba6STim Northover } while (Previous != Start && Previous->isDebugInstr()); 138cfef1803SAmara Emerson 139cfef1803SAmara Emerson if (TII.isTailCall(*SplitPoint) && 140cfef1803SAmara Emerson Previous->getOpcode() == TII.getCallFrameDestroyOpcode()) { 141cfef1803SAmara Emerson // Call frames cannot be nested, so if this frame is describing the tail 142cfef1803SAmara Emerson // call itself, then we must insert before the sequence even starts. For 143cfef1803SAmara Emerson // example: 144cfef1803SAmara Emerson // <split point> 145cfef1803SAmara Emerson // ADJCALLSTACKDOWN ... 146cfef1803SAmara Emerson // <Moves> 147cfef1803SAmara Emerson // ADJCALLSTACKUP ... 148cfef1803SAmara Emerson // TAILJMP somewhere 149cfef1803SAmara Emerson // On the other hand, it could be an unrelated call in which case this tail 150a87d3ba6STim Northover // call has no register moves of its own and should be the split point. For 151cfef1803SAmara Emerson // example: 152cfef1803SAmara Emerson // ADJCALLSTACKDOWN 153cfef1803SAmara Emerson // CALL something_else 154cfef1803SAmara Emerson // ADJCALLSTACKUP 155cfef1803SAmara Emerson // <split point> 156cfef1803SAmara Emerson // TAILJMP somewhere 157cfef1803SAmara Emerson do { 158cfef1803SAmara Emerson --Previous; 159cfef1803SAmara Emerson if (Previous->isCall()) 160cfef1803SAmara Emerson return SplitPoint; 161cfef1803SAmara Emerson } while(Previous->getOpcode() != TII.getCallFrameSetupOpcode()); 162cfef1803SAmara Emerson 163cfef1803SAmara Emerson return Previous; 164cfef1803SAmara Emerson } 165cfef1803SAmara Emerson 166cfef1803SAmara Emerson while (MIIsInTerminatorSequence(*Previous)) { 167cfef1803SAmara Emerson SplitPoint = Previous; 168cfef1803SAmara Emerson if (Previous == Start) 169cfef1803SAmara Emerson break; 170cfef1803SAmara Emerson --Previous; 171cfef1803SAmara Emerson } 172cfef1803SAmara Emerson 173cfef1803SAmara Emerson return SplitPoint; 174cfef1803SAmara Emerson } 175170a9031SSerge Pavlov 176fc3e6a81SMatt Arsenault FPClassTest llvm::invertFPClassTestIfSimpler(FPClassTest Test, bool UseFCmp) { 17764df9573SMatt Arsenault FPClassTest InvertedTest = ~Test; 178fc3e6a81SMatt Arsenault 17964df9573SMatt Arsenault // Pick the direction with fewer tests 18064df9573SMatt Arsenault // TODO: Handle more combinations of cases that can be handled together 18164df9573SMatt Arsenault switch (static_cast<unsigned>(InvertedTest)) { 182170a9031SSerge Pavlov case fcNan: 183170a9031SSerge Pavlov case fcSNan: 184170a9031SSerge Pavlov case fcQNan: 185170a9031SSerge Pavlov case fcInf: 186170a9031SSerge Pavlov case fcPosInf: 187170a9031SSerge Pavlov case fcNegInf: 188170a9031SSerge Pavlov case fcNormal: 189170a9031SSerge Pavlov case fcPosNormal: 190170a9031SSerge Pavlov case fcNegNormal: 191170a9031SSerge Pavlov case fcSubnormal: 192170a9031SSerge Pavlov case fcPosSubnormal: 193170a9031SSerge Pavlov case fcNegSubnormal: 194170a9031SSerge Pavlov case fcZero: 195170a9031SSerge Pavlov case fcPosZero: 196170a9031SSerge Pavlov case fcNegZero: 197170a9031SSerge Pavlov case fcFinite: 198170a9031SSerge Pavlov case fcPosFinite: 199170a9031SSerge Pavlov case fcNegFinite: 200b59022b4SMatt Arsenault case fcZero | fcNan: 20164df9573SMatt Arsenault case fcSubnormal | fcZero: 202b59022b4SMatt Arsenault case fcSubnormal | fcZero | fcNan: 203170a9031SSerge Pavlov return InvertedTest; 204fc3e6a81SMatt Arsenault case fcInf | fcNan: 205*77f1b481SMatt Arsenault case fcPosInf | fcNan: 206*77f1b481SMatt Arsenault case fcNegInf | fcNan: 207fc3e6a81SMatt Arsenault // If we're trying to use fcmp, we can take advantage of the nan check 208fc3e6a81SMatt Arsenault // behavior of the compare (but this is more instructions in the integer 209fc3e6a81SMatt Arsenault // expansion). 210fc3e6a81SMatt Arsenault return UseFCmp ? InvertedTest : fcNone; 21164df9573SMatt Arsenault default: 2127f81dd4dSSerge Pavlov return fcNone; 213170a9031SSerge Pavlov } 214facb3ac3SVladislav Dzhidzhoev 21564df9573SMatt Arsenault llvm_unreachable("covered FPClassTest"); 21664df9573SMatt Arsenault } 21764df9573SMatt Arsenault 218facb3ac3SVladislav Dzhidzhoev static MachineOperand *getSalvageOpsForCopy(const MachineRegisterInfo &MRI, 219facb3ac3SVladislav Dzhidzhoev MachineInstr &Copy) { 220facb3ac3SVladislav Dzhidzhoev assert(Copy.getOpcode() == TargetOpcode::COPY && "Must be a COPY"); 221facb3ac3SVladislav Dzhidzhoev 222facb3ac3SVladislav Dzhidzhoev return &Copy.getOperand(1); 223facb3ac3SVladislav Dzhidzhoev } 224facb3ac3SVladislav Dzhidzhoev 225facb3ac3SVladislav Dzhidzhoev static MachineOperand *getSalvageOpsForTrunc(const MachineRegisterInfo &MRI, 226facb3ac3SVladislav Dzhidzhoev MachineInstr &Trunc, 227facb3ac3SVladislav Dzhidzhoev SmallVectorImpl<uint64_t> &Ops) { 228facb3ac3SVladislav Dzhidzhoev assert(Trunc.getOpcode() == TargetOpcode::G_TRUNC && "Must be a G_TRUNC"); 229facb3ac3SVladislav Dzhidzhoev 230facb3ac3SVladislav Dzhidzhoev const auto FromLLT = MRI.getType(Trunc.getOperand(1).getReg()); 231facb3ac3SVladislav Dzhidzhoev const auto ToLLT = MRI.getType(Trunc.defs().begin()->getReg()); 232facb3ac3SVladislav Dzhidzhoev 233facb3ac3SVladislav Dzhidzhoev // TODO: Support non-scalar types. 234facb3ac3SVladislav Dzhidzhoev if (!FromLLT.isScalar()) { 235facb3ac3SVladislav Dzhidzhoev return nullptr; 236facb3ac3SVladislav Dzhidzhoev } 237facb3ac3SVladislav Dzhidzhoev 238facb3ac3SVladislav Dzhidzhoev auto ExtOps = DIExpression::getExtOps(FromLLT.getSizeInBits(), 239facb3ac3SVladislav Dzhidzhoev ToLLT.getSizeInBits(), false); 240facb3ac3SVladislav Dzhidzhoev Ops.append(ExtOps.begin(), ExtOps.end()); 241facb3ac3SVladislav Dzhidzhoev return &Trunc.getOperand(1); 242facb3ac3SVladislav Dzhidzhoev } 243facb3ac3SVladislav Dzhidzhoev 244facb3ac3SVladislav Dzhidzhoev static MachineOperand *salvageDebugInfoImpl(const MachineRegisterInfo &MRI, 245facb3ac3SVladislav Dzhidzhoev MachineInstr &MI, 246facb3ac3SVladislav Dzhidzhoev SmallVectorImpl<uint64_t> &Ops) { 247facb3ac3SVladislav Dzhidzhoev switch (MI.getOpcode()) { 248facb3ac3SVladislav Dzhidzhoev case TargetOpcode::G_TRUNC: 249facb3ac3SVladislav Dzhidzhoev return getSalvageOpsForTrunc(MRI, MI, Ops); 250facb3ac3SVladislav Dzhidzhoev case TargetOpcode::COPY: 251facb3ac3SVladislav Dzhidzhoev return getSalvageOpsForCopy(MRI, MI); 252facb3ac3SVladislav Dzhidzhoev default: 253facb3ac3SVladislav Dzhidzhoev return nullptr; 254facb3ac3SVladislav Dzhidzhoev } 255facb3ac3SVladislav Dzhidzhoev } 256facb3ac3SVladislav Dzhidzhoev 257facb3ac3SVladislav Dzhidzhoev void llvm::salvageDebugInfoForDbgValue(const MachineRegisterInfo &MRI, 258facb3ac3SVladislav Dzhidzhoev MachineInstr &MI, 259facb3ac3SVladislav Dzhidzhoev ArrayRef<MachineOperand *> DbgUsers) { 260facb3ac3SVladislav Dzhidzhoev // These are arbitrary chosen limits on the maximum number of values and the 261facb3ac3SVladislav Dzhidzhoev // maximum size of a debug expression we can salvage up to, used for 262facb3ac3SVladislav Dzhidzhoev // performance reasons. 263facb3ac3SVladislav Dzhidzhoev const unsigned MaxExpressionSize = 128; 264facb3ac3SVladislav Dzhidzhoev 265facb3ac3SVladislav Dzhidzhoev for (auto *DefMO : DbgUsers) { 266facb3ac3SVladislav Dzhidzhoev MachineInstr *DbgMI = DefMO->getParent(); 267facb3ac3SVladislav Dzhidzhoev if (DbgMI->isIndirectDebugValue()) { 268facb3ac3SVladislav Dzhidzhoev continue; 269facb3ac3SVladislav Dzhidzhoev } 270facb3ac3SVladislav Dzhidzhoev 271f6d431f2SXu Zhang int UseMOIdx = 272f6d431f2SXu Zhang DbgMI->findRegisterUseOperandIdx(DefMO->getReg(), /*TRI=*/nullptr); 273facb3ac3SVladislav Dzhidzhoev assert(UseMOIdx != -1 && DbgMI->hasDebugOperandForReg(DefMO->getReg()) && 274facb3ac3SVladislav Dzhidzhoev "Must use salvaged instruction as its location"); 275facb3ac3SVladislav Dzhidzhoev 276facb3ac3SVladislav Dzhidzhoev // TODO: Support DBG_VALUE_LIST. 277facb3ac3SVladislav Dzhidzhoev if (DbgMI->getOpcode() != TargetOpcode::DBG_VALUE) { 278facb3ac3SVladislav Dzhidzhoev assert(DbgMI->getOpcode() == TargetOpcode::DBG_VALUE_LIST && 279facb3ac3SVladislav Dzhidzhoev "Must be either DBG_VALUE or DBG_VALUE_LIST"); 280facb3ac3SVladislav Dzhidzhoev continue; 281facb3ac3SVladislav Dzhidzhoev } 282facb3ac3SVladislav Dzhidzhoev 283facb3ac3SVladislav Dzhidzhoev const DIExpression *SalvagedExpr = DbgMI->getDebugExpression(); 284facb3ac3SVladislav Dzhidzhoev 285facb3ac3SVladislav Dzhidzhoev SmallVector<uint64_t, 16> Ops; 286facb3ac3SVladislav Dzhidzhoev auto Op0 = salvageDebugInfoImpl(MRI, MI, Ops); 287facb3ac3SVladislav Dzhidzhoev if (!Op0) 288facb3ac3SVladislav Dzhidzhoev continue; 289facb3ac3SVladislav Dzhidzhoev SalvagedExpr = DIExpression::appendOpsToArg(SalvagedExpr, Ops, 0, true); 290facb3ac3SVladislav Dzhidzhoev 291facb3ac3SVladislav Dzhidzhoev bool IsValidSalvageExpr = 292facb3ac3SVladislav Dzhidzhoev SalvagedExpr->getNumElements() <= MaxExpressionSize; 293facb3ac3SVladislav Dzhidzhoev if (IsValidSalvageExpr) { 294facb3ac3SVladislav Dzhidzhoev auto &UseMO = DbgMI->getOperand(UseMOIdx); 295facb3ac3SVladislav Dzhidzhoev UseMO.setReg(Op0->getReg()); 296facb3ac3SVladislav Dzhidzhoev UseMO.setSubReg(Op0->getSubReg()); 297facb3ac3SVladislav Dzhidzhoev DbgMI->getDebugExpressionOp().setMetadata(SalvagedExpr); 298facb3ac3SVladislav Dzhidzhoev 299facb3ac3SVladislav Dzhidzhoev LLVM_DEBUG(dbgs() << "SALVAGE: " << *DbgMI << '\n'); 300facb3ac3SVladislav Dzhidzhoev } 301facb3ac3SVladislav Dzhidzhoev } 302facb3ac3SVladislav Dzhidzhoev } 303