xref: /llvm-project/llvm/lib/CodeGen/CodeGenCommonISel.cpp (revision 77f1b481b884621c12cde5f2ce6f080f11dbbbcc)
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