123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- //===-- CodeGenCommonISel.cpp ---------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines common utilies that are shared between SelectionDAG and
- // GlobalISel frameworks.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/CodeGen/CodeGenCommonISel.h"
- #include "llvm/Analysis/BranchProbabilityInfo.h"
- #include "llvm/CodeGen/MachineBasicBlock.h"
- #include "llvm/CodeGen/MachineFunction.h"
- #include "llvm/CodeGen/TargetInstrInfo.h"
- #include "llvm/CodeGen/TargetOpcodes.h"
- #include "llvm/IR/DebugInfoMetadata.h"
- #define DEBUG_TYPE "codegen-common"
- using namespace llvm;
- /// Add a successor MBB to ParentMBB< creating a new MachineBB for BB if SuccMBB
- /// is 0.
- MachineBasicBlock *
- StackProtectorDescriptor::addSuccessorMBB(
- const BasicBlock *BB, MachineBasicBlock *ParentMBB, bool IsLikely,
- MachineBasicBlock *SuccMBB) {
- // If SuccBB has not been created yet, create it.
- if (!SuccMBB) {
- MachineFunction *MF = ParentMBB->getParent();
- MachineFunction::iterator BBI(ParentMBB);
- SuccMBB = MF->CreateMachineBasicBlock(BB);
- MF->insert(++BBI, SuccMBB);
- }
- // Add it as a successor of ParentMBB.
- ParentMBB->addSuccessor(
- SuccMBB, BranchProbabilityInfo::getBranchProbStackProtector(IsLikely));
- return SuccMBB;
- }
- /// Given that the input MI is before a partial terminator sequence TSeq, return
- /// true if M + TSeq also a partial terminator sequence.
- ///
- /// A Terminator sequence is a sequence of MachineInstrs which at this point in
- /// lowering copy vregs into physical registers, which are then passed into
- /// terminator instructors so we can satisfy ABI constraints. A partial
- /// terminator sequence is an improper subset of a terminator sequence (i.e. it
- /// may be the whole terminator sequence).
- static bool MIIsInTerminatorSequence(const MachineInstr &MI) {
- // If we do not have a copy or an implicit def, we return true if and only if
- // MI is a debug value.
- if (!MI.isCopy() && !MI.isImplicitDef()) {
- // Sometimes DBG_VALUE MI sneak in between the copies from the vregs to the
- // physical registers if there is debug info associated with the terminator
- // of our mbb. We want to include said debug info in our terminator
- // sequence, so we return true in that case.
- if (MI.isDebugInstr())
- return true;
- // For GlobalISel, we may have extension instructions for arguments within
- // copy sequences. Allow these.
- switch (MI.getOpcode()) {
- case TargetOpcode::G_TRUNC:
- case TargetOpcode::G_ZEXT:
- case TargetOpcode::G_ANYEXT:
- case TargetOpcode::G_SEXT:
- case TargetOpcode::G_MERGE_VALUES:
- case TargetOpcode::G_UNMERGE_VALUES:
- case TargetOpcode::G_CONCAT_VECTORS:
- case TargetOpcode::G_BUILD_VECTOR:
- case TargetOpcode::G_EXTRACT:
- return true;
- default:
- return false;
- }
- }
- // We have left the terminator sequence if we are not doing one of the
- // following:
- //
- // 1. Copying a vreg into a physical register.
- // 2. Copying a vreg into a vreg.
- // 3. Defining a register via an implicit def.
- // OPI should always be a register definition...
- MachineInstr::const_mop_iterator OPI = MI.operands_begin();
- if (!OPI->isReg() || !OPI->isDef())
- return false;
- // Defining any register via an implicit def is always ok.
- if (MI.isImplicitDef())
- return true;
- // Grab the copy source...
- MachineInstr::const_mop_iterator OPI2 = OPI;
- ++OPI2;
- assert(OPI2 != MI.operands_end()
- && "Should have a copy implying we should have 2 arguments.");
- // Make sure that the copy dest is not a vreg when the copy source is a
- // physical register.
- if (!OPI2->isReg() ||
- (!OPI->getReg().isPhysical() && OPI2->getReg().isPhysical()))
- return false;
- return true;
- }
- /// Find the split point at which to splice the end of BB into its success stack
- /// protector check machine basic block.
- ///
- /// On many platforms, due to ABI constraints, terminators, even before register
- /// allocation, use physical registers. This creates an issue for us since
- /// physical registers at this point can not travel across basic
- /// blocks. Luckily, selectiondag always moves physical registers into vregs
- /// when they enter functions and moves them through a sequence of copies back
- /// into the physical registers right before the terminator creating a
- /// ``Terminator Sequence''. This function is searching for the beginning of the
- /// terminator sequence so that we can ensure that we splice off not just the
- /// terminator, but additionally the copies that move the vregs into the
- /// physical registers.
- MachineBasicBlock::iterator
- llvm::findSplitPointForStackProtector(MachineBasicBlock *BB,
- const TargetInstrInfo &TII) {
- MachineBasicBlock::iterator SplitPoint = BB->getFirstTerminator();
- if (SplitPoint == BB->begin())
- return SplitPoint;
- MachineBasicBlock::iterator Start = BB->begin();
- MachineBasicBlock::iterator Previous = SplitPoint;
- do {
- --Previous;
- } while (Previous != Start && Previous->isDebugInstr());
- if (TII.isTailCall(*SplitPoint) &&
- Previous->getOpcode() == TII.getCallFrameDestroyOpcode()) {
- // Call frames cannot be nested, so if this frame is describing the tail
- // call itself, then we must insert before the sequence even starts. For
- // example:
- // <split point>
- // ADJCALLSTACKDOWN ...
- // <Moves>
- // ADJCALLSTACKUP ...
- // TAILJMP somewhere
- // On the other hand, it could be an unrelated call in which case this tail
- // call has no register moves of its own and should be the split point. For
- // example:
- // ADJCALLSTACKDOWN
- // CALL something_else
- // ADJCALLSTACKUP
- // <split point>
- // TAILJMP somewhere
- do {
- --Previous;
- if (Previous->isCall())
- return SplitPoint;
- } while(Previous->getOpcode() != TII.getCallFrameSetupOpcode());
- return Previous;
- }
- while (MIIsInTerminatorSequence(*Previous)) {
- SplitPoint = Previous;
- if (Previous == Start)
- break;
- --Previous;
- }
- return SplitPoint;
- }
- unsigned llvm::getInvertedFPClassTest(unsigned Test) {
- unsigned InvertedTest = ~Test & fcAllFlags;
- switch (InvertedTest) {
- default:
- break;
- case fcNan:
- case fcSNan:
- case fcQNan:
- case fcInf:
- case fcPosInf:
- case fcNegInf:
- case fcNormal:
- case fcPosNormal:
- case fcNegNormal:
- case fcSubnormal:
- case fcPosSubnormal:
- case fcNegSubnormal:
- case fcZero:
- case fcPosZero:
- case fcNegZero:
- case fcFinite:
- case fcPosFinite:
- case fcNegFinite:
- return InvertedTest;
- }
- return 0;
- }
- static MachineOperand *getSalvageOpsForCopy(const MachineRegisterInfo &MRI,
- MachineInstr &Copy) {
- assert(Copy.getOpcode() == TargetOpcode::COPY && "Must be a COPY");
- return &Copy.getOperand(1);
- }
- static MachineOperand *getSalvageOpsForTrunc(const MachineRegisterInfo &MRI,
- MachineInstr &Trunc,
- SmallVectorImpl<uint64_t> &Ops) {
- assert(Trunc.getOpcode() == TargetOpcode::G_TRUNC && "Must be a G_TRUNC");
- const auto FromLLT = MRI.getType(Trunc.getOperand(1).getReg());
- const auto ToLLT = MRI.getType(Trunc.defs().begin()->getReg());
- // TODO: Support non-scalar types.
- if (!FromLLT.isScalar()) {
- return nullptr;
- }
- auto ExtOps = DIExpression::getExtOps(FromLLT.getSizeInBits(),
- ToLLT.getSizeInBits(), false);
- Ops.append(ExtOps.begin(), ExtOps.end());
- return &Trunc.getOperand(1);
- }
- static MachineOperand *salvageDebugInfoImpl(const MachineRegisterInfo &MRI,
- MachineInstr &MI,
- SmallVectorImpl<uint64_t> &Ops) {
- switch (MI.getOpcode()) {
- case TargetOpcode::G_TRUNC:
- return getSalvageOpsForTrunc(MRI, MI, Ops);
- case TargetOpcode::COPY:
- return getSalvageOpsForCopy(MRI, MI);
- default:
- return nullptr;
- }
- }
- void llvm::salvageDebugInfoForDbgValue(const MachineRegisterInfo &MRI,
- MachineInstr &MI,
- ArrayRef<MachineOperand *> DbgUsers) {
- // These are arbitrary chosen limits on the maximum number of values and the
- // maximum size of a debug expression we can salvage up to, used for
- // performance reasons.
- const unsigned MaxExpressionSize = 128;
- for (auto *DefMO : DbgUsers) {
- MachineInstr *DbgMI = DefMO->getParent();
- if (DbgMI->isIndirectDebugValue()) {
- continue;
- }
- int UseMOIdx = DbgMI->findRegisterUseOperandIdx(DefMO->getReg());
- assert(UseMOIdx != -1 && DbgMI->hasDebugOperandForReg(DefMO->getReg()) &&
- "Must use salvaged instruction as its location");
- // TODO: Support DBG_VALUE_LIST.
- if (DbgMI->getOpcode() != TargetOpcode::DBG_VALUE) {
- assert(DbgMI->getOpcode() == TargetOpcode::DBG_VALUE_LIST &&
- "Must be either DBG_VALUE or DBG_VALUE_LIST");
- continue;
- }
- const DIExpression *SalvagedExpr = DbgMI->getDebugExpression();
- SmallVector<uint64_t, 16> Ops;
- auto Op0 = salvageDebugInfoImpl(MRI, MI, Ops);
- if (!Op0)
- continue;
- SalvagedExpr = DIExpression::appendOpsToArg(SalvagedExpr, Ops, 0, true);
- bool IsValidSalvageExpr =
- SalvagedExpr->getNumElements() <= MaxExpressionSize;
- if (IsValidSalvageExpr) {
- auto &UseMO = DbgMI->getOperand(UseMOIdx);
- UseMO.setReg(Op0->getReg());
- UseMO.setSubReg(Op0->getSubReg());
- DbgMI->getDebugExpressionOp().setMetadata(SalvagedExpr);
- LLVM_DEBUG(dbgs() << "SALVAGE: " << *DbgMI << '\n');
- }
- }
- }
|