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"
20cfef1803SAmara Emerson
21cfef1803SAmara Emerson using namespace llvm;
22cfef1803SAmara Emerson
23cfef1803SAmara Emerson /// Add a successor MBB to ParentMBB< creating a new MachineBB for BB if SuccMBB
24cfef1803SAmara Emerson /// is 0.
25cfef1803SAmara Emerson MachineBasicBlock *
addSuccessorMBB(const BasicBlock * BB,MachineBasicBlock * ParentMBB,bool IsLikely,MachineBasicBlock * SuccMBB)26cfef1803SAmara Emerson StackProtectorDescriptor::addSuccessorMBB(
27cfef1803SAmara Emerson const BasicBlock *BB, MachineBasicBlock *ParentMBB, bool IsLikely,
28cfef1803SAmara Emerson MachineBasicBlock *SuccMBB) {
29cfef1803SAmara Emerson // If SuccBB has not been created yet, create it.
30cfef1803SAmara Emerson if (!SuccMBB) {
31cfef1803SAmara Emerson MachineFunction *MF = ParentMBB->getParent();
32cfef1803SAmara Emerson MachineFunction::iterator BBI(ParentMBB);
33cfef1803SAmara Emerson SuccMBB = MF->CreateMachineBasicBlock(BB);
34cfef1803SAmara Emerson MF->insert(++BBI, SuccMBB);
35cfef1803SAmara Emerson }
36cfef1803SAmara Emerson // Add it as a successor of ParentMBB.
37cfef1803SAmara Emerson ParentMBB->addSuccessor(
38cfef1803SAmara Emerson SuccMBB, BranchProbabilityInfo::getBranchProbStackProtector(IsLikely));
39cfef1803SAmara Emerson return SuccMBB;
40cfef1803SAmara Emerson }
41cfef1803SAmara Emerson
42cfef1803SAmara Emerson /// Given that the input MI is before a partial terminator sequence TSeq, return
43cfef1803SAmara Emerson /// true if M + TSeq also a partial terminator sequence.
44cfef1803SAmara Emerson ///
45cfef1803SAmara Emerson /// A Terminator sequence is a sequence of MachineInstrs which at this point in
46cfef1803SAmara Emerson /// lowering copy vregs into physical registers, which are then passed into
47cfef1803SAmara Emerson /// terminator instructors so we can satisfy ABI constraints. A partial
48cfef1803SAmara Emerson /// terminator sequence is an improper subset of a terminator sequence (i.e. it
49cfef1803SAmara Emerson /// may be the whole terminator sequence).
MIIsInTerminatorSequence(const MachineInstr & MI)50cfef1803SAmara Emerson static bool MIIsInTerminatorSequence(const MachineInstr &MI) {
51cfef1803SAmara Emerson // If we do not have a copy or an implicit def, we return true if and only if
52cfef1803SAmara Emerson // MI is a debug value.
53cfef1803SAmara Emerson if (!MI.isCopy() && !MI.isImplicitDef()) {
54cfef1803SAmara Emerson // Sometimes DBG_VALUE MI sneak in between the copies from the vregs to the
55cfef1803SAmara Emerson // physical registers if there is debug info associated with the terminator
56cfef1803SAmara Emerson // of our mbb. We want to include said debug info in our terminator
57cfef1803SAmara Emerson // sequence, so we return true in that case.
58cfef1803SAmara Emerson if (MI.isDebugInstr())
59cfef1803SAmara Emerson return true;
60cfef1803SAmara Emerson
61cfef1803SAmara Emerson // For GlobalISel, we may have extension instructions for arguments within
62cfef1803SAmara Emerson // copy sequences. Allow these.
63cfef1803SAmara Emerson switch (MI.getOpcode()) {
64cfef1803SAmara Emerson case TargetOpcode::G_TRUNC:
65cfef1803SAmara Emerson case TargetOpcode::G_ZEXT:
66cfef1803SAmara Emerson case TargetOpcode::G_ANYEXT:
67cfef1803SAmara Emerson case TargetOpcode::G_SEXT:
68cfef1803SAmara Emerson case TargetOpcode::G_MERGE_VALUES:
69cfef1803SAmara Emerson case TargetOpcode::G_UNMERGE_VALUES:
70cfef1803SAmara Emerson case TargetOpcode::G_CONCAT_VECTORS:
71cfef1803SAmara Emerson case TargetOpcode::G_BUILD_VECTOR:
72cfef1803SAmara Emerson case TargetOpcode::G_EXTRACT:
73cfef1803SAmara Emerson return true;
74cfef1803SAmara Emerson default:
75cfef1803SAmara Emerson return false;
76cfef1803SAmara Emerson }
77cfef1803SAmara Emerson }
78cfef1803SAmara Emerson
79cfef1803SAmara Emerson // We have left the terminator sequence if we are not doing one of the
80cfef1803SAmara Emerson // following:
81cfef1803SAmara Emerson //
82cfef1803SAmara Emerson // 1. Copying a vreg into a physical register.
83cfef1803SAmara Emerson // 2. Copying a vreg into a vreg.
84cfef1803SAmara Emerson // 3. Defining a register via an implicit def.
85cfef1803SAmara Emerson
86cfef1803SAmara Emerson // OPI should always be a register definition...
87cfef1803SAmara Emerson MachineInstr::const_mop_iterator OPI = MI.operands_begin();
88cfef1803SAmara Emerson if (!OPI->isReg() || !OPI->isDef())
89cfef1803SAmara Emerson return false;
90cfef1803SAmara Emerson
91cfef1803SAmara Emerson // Defining any register via an implicit def is always ok.
92cfef1803SAmara Emerson if (MI.isImplicitDef())
93cfef1803SAmara Emerson return true;
94cfef1803SAmara Emerson
95cfef1803SAmara Emerson // Grab the copy source...
96cfef1803SAmara Emerson MachineInstr::const_mop_iterator OPI2 = OPI;
97cfef1803SAmara Emerson ++OPI2;
98cfef1803SAmara Emerson assert(OPI2 != MI.operands_end()
99cfef1803SAmara Emerson && "Should have a copy implying we should have 2 arguments.");
100cfef1803SAmara Emerson
101cfef1803SAmara Emerson // Make sure that the copy dest is not a vreg when the copy source is a
102cfef1803SAmara Emerson // physical register.
103cfef1803SAmara Emerson if (!OPI2->isReg() || (!Register::isPhysicalRegister(OPI->getReg()) &&
104cfef1803SAmara Emerson Register::isPhysicalRegister(OPI2->getReg())))
105cfef1803SAmara Emerson return false;
106cfef1803SAmara Emerson
107cfef1803SAmara Emerson return true;
108cfef1803SAmara Emerson }
109cfef1803SAmara Emerson
110cfef1803SAmara Emerson /// Find the split point at which to splice the end of BB into its success stack
111cfef1803SAmara Emerson /// protector check machine basic block.
112cfef1803SAmara Emerson ///
113cfef1803SAmara Emerson /// On many platforms, due to ABI constraints, terminators, even before register
114cfef1803SAmara Emerson /// allocation, use physical registers. This creates an issue for us since
115cfef1803SAmara Emerson /// physical registers at this point can not travel across basic
116cfef1803SAmara Emerson /// blocks. Luckily, selectiondag always moves physical registers into vregs
117cfef1803SAmara Emerson /// when they enter functions and moves them through a sequence of copies back
118cfef1803SAmara Emerson /// into the physical registers right before the terminator creating a
119cfef1803SAmara Emerson /// ``Terminator Sequence''. This function is searching for the beginning of the
120cfef1803SAmara Emerson /// terminator sequence so that we can ensure that we splice off not just the
121cfef1803SAmara Emerson /// terminator, but additionally the copies that move the vregs into the
122cfef1803SAmara Emerson /// physical registers.
123cfef1803SAmara Emerson MachineBasicBlock::iterator
findSplitPointForStackProtector(MachineBasicBlock * BB,const TargetInstrInfo & TII)124cfef1803SAmara Emerson llvm::findSplitPointForStackProtector(MachineBasicBlock *BB,
125cfef1803SAmara Emerson const TargetInstrInfo &TII) {
126cfef1803SAmara Emerson MachineBasicBlock::iterator SplitPoint = BB->getFirstTerminator();
127cfef1803SAmara Emerson if (SplitPoint == BB->begin())
128cfef1803SAmara Emerson return SplitPoint;
129cfef1803SAmara Emerson
130cfef1803SAmara Emerson MachineBasicBlock::iterator Start = BB->begin();
131cfef1803SAmara Emerson MachineBasicBlock::iterator Previous = SplitPoint;
132a87d3ba6STim Northover do {
133cfef1803SAmara Emerson --Previous;
134a87d3ba6STim Northover } while (Previous != Start && Previous->isDebugInstr());
135cfef1803SAmara Emerson
136cfef1803SAmara Emerson if (TII.isTailCall(*SplitPoint) &&
137cfef1803SAmara Emerson Previous->getOpcode() == TII.getCallFrameDestroyOpcode()) {
138cfef1803SAmara Emerson // Call frames cannot be nested, so if this frame is describing the tail
139cfef1803SAmara Emerson // call itself, then we must insert before the sequence even starts. For
140cfef1803SAmara Emerson // example:
141cfef1803SAmara Emerson // <split point>
142cfef1803SAmara Emerson // ADJCALLSTACKDOWN ...
143cfef1803SAmara Emerson // <Moves>
144cfef1803SAmara Emerson // ADJCALLSTACKUP ...
145cfef1803SAmara Emerson // TAILJMP somewhere
146cfef1803SAmara Emerson // On the other hand, it could be an unrelated call in which case this tail
147a87d3ba6STim Northover // call has no register moves of its own and should be the split point. For
148cfef1803SAmara Emerson // example:
149cfef1803SAmara Emerson // ADJCALLSTACKDOWN
150cfef1803SAmara Emerson // CALL something_else
151cfef1803SAmara Emerson // ADJCALLSTACKUP
152cfef1803SAmara Emerson // <split point>
153cfef1803SAmara Emerson // TAILJMP somewhere
154cfef1803SAmara Emerson do {
155cfef1803SAmara Emerson --Previous;
156cfef1803SAmara Emerson if (Previous->isCall())
157cfef1803SAmara Emerson return SplitPoint;
158cfef1803SAmara Emerson } while(Previous->getOpcode() != TII.getCallFrameSetupOpcode());
159cfef1803SAmara Emerson
160cfef1803SAmara Emerson return Previous;
161cfef1803SAmara Emerson }
162cfef1803SAmara Emerson
163cfef1803SAmara Emerson while (MIIsInTerminatorSequence(*Previous)) {
164cfef1803SAmara Emerson SplitPoint = Previous;
165cfef1803SAmara Emerson if (Previous == Start)
166cfef1803SAmara Emerson break;
167cfef1803SAmara Emerson --Previous;
168cfef1803SAmara Emerson }
169cfef1803SAmara Emerson
170cfef1803SAmara Emerson return SplitPoint;
171cfef1803SAmara Emerson }
172*170a9031SSerge Pavlov
getInvertedFPClassTest(unsigned Test)173*170a9031SSerge Pavlov unsigned llvm::getInvertedFPClassTest(unsigned Test) {
174*170a9031SSerge Pavlov unsigned InvertedTest = ~Test & fcAllFlags;
175*170a9031SSerge Pavlov switch (InvertedTest) {
176*170a9031SSerge Pavlov default:
177*170a9031SSerge Pavlov break;
178*170a9031SSerge Pavlov case fcNan:
179*170a9031SSerge Pavlov case fcSNan:
180*170a9031SSerge Pavlov case fcQNan:
181*170a9031SSerge Pavlov case fcInf:
182*170a9031SSerge Pavlov case fcPosInf:
183*170a9031SSerge Pavlov case fcNegInf:
184*170a9031SSerge Pavlov case fcNormal:
185*170a9031SSerge Pavlov case fcPosNormal:
186*170a9031SSerge Pavlov case fcNegNormal:
187*170a9031SSerge Pavlov case fcSubnormal:
188*170a9031SSerge Pavlov case fcPosSubnormal:
189*170a9031SSerge Pavlov case fcNegSubnormal:
190*170a9031SSerge Pavlov case fcZero:
191*170a9031SSerge Pavlov case fcPosZero:
192*170a9031SSerge Pavlov case fcNegZero:
193*170a9031SSerge Pavlov case fcFinite:
194*170a9031SSerge Pavlov case fcPosFinite:
195*170a9031SSerge Pavlov case fcNegFinite:
196*170a9031SSerge Pavlov return InvertedTest;
197*170a9031SSerge Pavlov }
198*170a9031SSerge Pavlov return 0;
199*170a9031SSerge Pavlov }
200