Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp
35232 views
//===-- CodeGenCommonISel.cpp ---------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines common utilies that are shared between SelectionDAG and9// GlobalISel frameworks.10//11//===----------------------------------------------------------------------===//1213#include "llvm/CodeGen/CodeGenCommonISel.h"14#include "llvm/Analysis/BranchProbabilityInfo.h"15#include "llvm/CodeGen/MachineBasicBlock.h"16#include "llvm/CodeGen/MachineFunction.h"17#include "llvm/CodeGen/TargetInstrInfo.h"18#include "llvm/CodeGen/TargetOpcodes.h"19#include "llvm/IR/DebugInfoMetadata.h"2021#define DEBUG_TYPE "codegen-common"2223using namespace llvm;2425/// Add a successor MBB to ParentMBB< creating a new MachineBB for BB if SuccMBB26/// is 0.27MachineBasicBlock *28StackProtectorDescriptor::addSuccessorMBB(29const BasicBlock *BB, MachineBasicBlock *ParentMBB, bool IsLikely,30MachineBasicBlock *SuccMBB) {31// If SuccBB has not been created yet, create it.32if (!SuccMBB) {33MachineFunction *MF = ParentMBB->getParent();34MachineFunction::iterator BBI(ParentMBB);35SuccMBB = MF->CreateMachineBasicBlock(BB);36MF->insert(++BBI, SuccMBB);37}38// Add it as a successor of ParentMBB.39ParentMBB->addSuccessor(40SuccMBB, BranchProbabilityInfo::getBranchProbStackProtector(IsLikely));41return SuccMBB;42}4344/// Given that the input MI is before a partial terminator sequence TSeq, return45/// true if M + TSeq also a partial terminator sequence.46///47/// A Terminator sequence is a sequence of MachineInstrs which at this point in48/// lowering copy vregs into physical registers, which are then passed into49/// terminator instructors so we can satisfy ABI constraints. A partial50/// terminator sequence is an improper subset of a terminator sequence (i.e. it51/// may be the whole terminator sequence).52static bool MIIsInTerminatorSequence(const MachineInstr &MI) {53// If we do not have a copy or an implicit def, we return true if and only if54// MI is a debug value.55if (!MI.isCopy() && !MI.isImplicitDef()) {56// Sometimes DBG_VALUE MI sneak in between the copies from the vregs to the57// physical registers if there is debug info associated with the terminator58// of our mbb. We want to include said debug info in our terminator59// sequence, so we return true in that case.60if (MI.isDebugInstr())61return true;6263// For GlobalISel, we may have extension instructions for arguments within64// copy sequences. Allow these.65switch (MI.getOpcode()) {66case TargetOpcode::G_TRUNC:67case TargetOpcode::G_ZEXT:68case TargetOpcode::G_ANYEXT:69case TargetOpcode::G_SEXT:70case TargetOpcode::G_MERGE_VALUES:71case TargetOpcode::G_UNMERGE_VALUES:72case TargetOpcode::G_CONCAT_VECTORS:73case TargetOpcode::G_BUILD_VECTOR:74case TargetOpcode::G_EXTRACT:75return true;76default:77return false;78}79}8081// We have left the terminator sequence if we are not doing one of the82// following:83//84// 1. Copying a vreg into a physical register.85// 2. Copying a vreg into a vreg.86// 3. Defining a register via an implicit def.8788// OPI should always be a register definition...89MachineInstr::const_mop_iterator OPI = MI.operands_begin();90if (!OPI->isReg() || !OPI->isDef())91return false;9293// Defining any register via an implicit def is always ok.94if (MI.isImplicitDef())95return true;9697// Grab the copy source...98MachineInstr::const_mop_iterator OPI2 = OPI;99++OPI2;100assert(OPI2 != MI.operands_end()101&& "Should have a copy implying we should have 2 arguments.");102103// Make sure that the copy dest is not a vreg when the copy source is a104// physical register.105if (!OPI2->isReg() ||106(!OPI->getReg().isPhysical() && OPI2->getReg().isPhysical()))107return false;108109return true;110}111112/// Find the split point at which to splice the end of BB into its success stack113/// protector check machine basic block.114///115/// On many platforms, due to ABI constraints, terminators, even before register116/// allocation, use physical registers. This creates an issue for us since117/// physical registers at this point can not travel across basic118/// blocks. Luckily, selectiondag always moves physical registers into vregs119/// when they enter functions and moves them through a sequence of copies back120/// into the physical registers right before the terminator creating a121/// ``Terminator Sequence''. This function is searching for the beginning of the122/// terminator sequence so that we can ensure that we splice off not just the123/// terminator, but additionally the copies that move the vregs into the124/// physical registers.125MachineBasicBlock::iterator126llvm::findSplitPointForStackProtector(MachineBasicBlock *BB,127const TargetInstrInfo &TII) {128MachineBasicBlock::iterator SplitPoint = BB->getFirstTerminator();129if (SplitPoint == BB->begin())130return SplitPoint;131132MachineBasicBlock::iterator Start = BB->begin();133MachineBasicBlock::iterator Previous = SplitPoint;134do {135--Previous;136} while (Previous != Start && Previous->isDebugInstr());137138if (TII.isTailCall(*SplitPoint) &&139Previous->getOpcode() == TII.getCallFrameDestroyOpcode()) {140// Call frames cannot be nested, so if this frame is describing the tail141// call itself, then we must insert before the sequence even starts. For142// example:143// <split point>144// ADJCALLSTACKDOWN ...145// <Moves>146// ADJCALLSTACKUP ...147// TAILJMP somewhere148// On the other hand, it could be an unrelated call in which case this tail149// call has no register moves of its own and should be the split point. For150// example:151// ADJCALLSTACKDOWN152// CALL something_else153// ADJCALLSTACKUP154// <split point>155// TAILJMP somewhere156do {157--Previous;158if (Previous->isCall())159return SplitPoint;160} while(Previous->getOpcode() != TII.getCallFrameSetupOpcode());161162return Previous;163}164165while (MIIsInTerminatorSequence(*Previous)) {166SplitPoint = Previous;167if (Previous == Start)168break;169--Previous;170}171172return SplitPoint;173}174175FPClassTest llvm::invertFPClassTestIfSimpler(FPClassTest Test) {176FPClassTest InvertedTest = ~Test;177// Pick the direction with fewer tests178// TODO: Handle more combinations of cases that can be handled together179switch (static_cast<unsigned>(InvertedTest)) {180case fcNan:181case fcSNan:182case fcQNan:183case fcInf:184case fcPosInf:185case fcNegInf:186case fcNormal:187case fcPosNormal:188case fcNegNormal:189case fcSubnormal:190case fcPosSubnormal:191case fcNegSubnormal:192case fcZero:193case fcPosZero:194case fcNegZero:195case fcFinite:196case fcPosFinite:197case fcNegFinite:198case fcZero | fcNan:199case fcSubnormal | fcZero:200case fcSubnormal | fcZero | fcNan:201return InvertedTest;202default:203return fcNone;204}205206llvm_unreachable("covered FPClassTest");207}208209static MachineOperand *getSalvageOpsForCopy(const MachineRegisterInfo &MRI,210MachineInstr &Copy) {211assert(Copy.getOpcode() == TargetOpcode::COPY && "Must be a COPY");212213return &Copy.getOperand(1);214}215216static MachineOperand *getSalvageOpsForTrunc(const MachineRegisterInfo &MRI,217MachineInstr &Trunc,218SmallVectorImpl<uint64_t> &Ops) {219assert(Trunc.getOpcode() == TargetOpcode::G_TRUNC && "Must be a G_TRUNC");220221const auto FromLLT = MRI.getType(Trunc.getOperand(1).getReg());222const auto ToLLT = MRI.getType(Trunc.defs().begin()->getReg());223224// TODO: Support non-scalar types.225if (!FromLLT.isScalar()) {226return nullptr;227}228229auto ExtOps = DIExpression::getExtOps(FromLLT.getSizeInBits(),230ToLLT.getSizeInBits(), false);231Ops.append(ExtOps.begin(), ExtOps.end());232return &Trunc.getOperand(1);233}234235static MachineOperand *salvageDebugInfoImpl(const MachineRegisterInfo &MRI,236MachineInstr &MI,237SmallVectorImpl<uint64_t> &Ops) {238switch (MI.getOpcode()) {239case TargetOpcode::G_TRUNC:240return getSalvageOpsForTrunc(MRI, MI, Ops);241case TargetOpcode::COPY:242return getSalvageOpsForCopy(MRI, MI);243default:244return nullptr;245}246}247248void llvm::salvageDebugInfoForDbgValue(const MachineRegisterInfo &MRI,249MachineInstr &MI,250ArrayRef<MachineOperand *> DbgUsers) {251// These are arbitrary chosen limits on the maximum number of values and the252// maximum size of a debug expression we can salvage up to, used for253// performance reasons.254const unsigned MaxExpressionSize = 128;255256for (auto *DefMO : DbgUsers) {257MachineInstr *DbgMI = DefMO->getParent();258if (DbgMI->isIndirectDebugValue()) {259continue;260}261262int UseMOIdx =263DbgMI->findRegisterUseOperandIdx(DefMO->getReg(), /*TRI=*/nullptr);264assert(UseMOIdx != -1 && DbgMI->hasDebugOperandForReg(DefMO->getReg()) &&265"Must use salvaged instruction as its location");266267// TODO: Support DBG_VALUE_LIST.268if (DbgMI->getOpcode() != TargetOpcode::DBG_VALUE) {269assert(DbgMI->getOpcode() == TargetOpcode::DBG_VALUE_LIST &&270"Must be either DBG_VALUE or DBG_VALUE_LIST");271continue;272}273274const DIExpression *SalvagedExpr = DbgMI->getDebugExpression();275276SmallVector<uint64_t, 16> Ops;277auto Op0 = salvageDebugInfoImpl(MRI, MI, Ops);278if (!Op0)279continue;280SalvagedExpr = DIExpression::appendOpsToArg(SalvagedExpr, Ops, 0, true);281282bool IsValidSalvageExpr =283SalvagedExpr->getNumElements() <= MaxExpressionSize;284if (IsValidSalvageExpr) {285auto &UseMO = DbgMI->getOperand(UseMOIdx);286UseMO.setReg(Op0->getReg());287UseMO.setSubReg(Op0->getSubReg());288DbgMI->getDebugExpressionOp().setMetadata(SalvagedExpr);289290LLVM_DEBUG(dbgs() << "SALVAGE: " << *DbgMI << '\n');291}292}293}294295296