1 //===- NVPTXInstrInfo.cpp - NVPTX Instruction Information -----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the NVPTX implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "NVPTXInstrInfo.h"
15 #include "NVPTX.h"
16 #include "NVPTXTargetMachine.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/IR/Function.h"
22 
23 using namespace llvm;
24 
25 #define GET_INSTRINFO_CTOR_DTOR
26 #include "NVPTXGenInstrInfo.inc"
27 
28 // Pin the vtable to this file.
anchor()29 void NVPTXInstrInfo::anchor() {}
30 
NVPTXInstrInfo()31 NVPTXInstrInfo::NVPTXInstrInfo() : NVPTXGenInstrInfo(), RegInfo() {}
32 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,const DebugLoc & DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const33 void NVPTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
34                                  MachineBasicBlock::iterator I,
35                                  const DebugLoc &DL, unsigned DestReg,
36                                  unsigned SrcReg, bool KillSrc) const {
37   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
38   const TargetRegisterClass *DestRC = MRI.getRegClass(DestReg);
39   const TargetRegisterClass *SrcRC = MRI.getRegClass(SrcReg);
40 
41   if (RegInfo.getRegSizeInBits(*DestRC) != RegInfo.getRegSizeInBits(*SrcRC))
42     report_fatal_error("Copy one register into another with a different width");
43 
44   unsigned Op;
45   if (DestRC == &NVPTX::Int1RegsRegClass) {
46     Op = NVPTX::IMOV1rr;
47   } else if (DestRC == &NVPTX::Int16RegsRegClass) {
48     Op = NVPTX::IMOV16rr;
49   } else if (DestRC == &NVPTX::Int32RegsRegClass) {
50     Op = (SrcRC == &NVPTX::Int32RegsRegClass ? NVPTX::IMOV32rr
51                                              : NVPTX::BITCONVERT_32_F2I);
52   } else if (DestRC == &NVPTX::Int64RegsRegClass) {
53     Op = (SrcRC == &NVPTX::Int64RegsRegClass ? NVPTX::IMOV64rr
54                                              : NVPTX::BITCONVERT_64_F2I);
55   } else if (DestRC == &NVPTX::Float16RegsRegClass) {
56     Op = (SrcRC == &NVPTX::Float16RegsRegClass ? NVPTX::FMOV16rr
57                                                : NVPTX::BITCONVERT_16_I2F);
58   } else if (DestRC == &NVPTX::Float16x2RegsRegClass) {
59     Op = NVPTX::IMOV32rr;
60   } else if (DestRC == &NVPTX::Float32RegsRegClass) {
61     Op = (SrcRC == &NVPTX::Float32RegsRegClass ? NVPTX::FMOV32rr
62                                                : NVPTX::BITCONVERT_32_I2F);
63   } else if (DestRC == &NVPTX::Float64RegsRegClass) {
64     Op = (SrcRC == &NVPTX::Float64RegsRegClass ? NVPTX::FMOV64rr
65                                                : NVPTX::BITCONVERT_64_I2F);
66   } else {
67     llvm_unreachable("Bad register copy");
68   }
69   BuildMI(MBB, I, DL, get(Op), DestReg)
70       .addReg(SrcReg, getKillRegState(KillSrc));
71 }
72 
73 /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
74 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
75 /// implemented for a target).  Upon success, this returns false and returns
76 /// with the following information in various cases:
77 ///
78 /// 1. If this block ends with no branches (it just falls through to its succ)
79 ///    just return false, leaving TBB/FBB null.
80 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
81 ///    the destination block.
82 /// 3. If this block ends with an conditional branch and it falls through to
83 ///    an successor block, it sets TBB to be the branch destination block and a
84 ///    list of operands that evaluate the condition. These
85 ///    operands can be passed to other TargetInstrInfo methods to create new
86 ///    branches.
87 /// 4. If this block ends with an conditional branch and an unconditional
88 ///    block, it returns the 'true' destination in TBB, the 'false' destination
89 ///    in FBB, and a list of operands that evaluate the condition. These
90 ///    operands can be passed to other TargetInstrInfo methods to create new
91 ///    branches.
92 ///
93 /// Note that removeBranch and insertBranch must be implemented to support
94 /// cases where this method returns success.
95 ///
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const96 bool NVPTXInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
97                                    MachineBasicBlock *&TBB,
98                                    MachineBasicBlock *&FBB,
99                                    SmallVectorImpl<MachineOperand> &Cond,
100                                    bool AllowModify) const {
101   // If the block has no terminators, it just falls into the block after it.
102   MachineBasicBlock::iterator I = MBB.end();
103   if (I == MBB.begin() || !isUnpredicatedTerminator(*--I))
104     return false;
105 
106   // Get the last instruction in the block.
107   MachineInstr &LastInst = *I;
108 
109   // If there is only one terminator instruction, process it.
110   if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
111     if (LastInst.getOpcode() == NVPTX::GOTO) {
112       TBB = LastInst.getOperand(0).getMBB();
113       return false;
114     } else if (LastInst.getOpcode() == NVPTX::CBranch) {
115       // Block ends with fall-through condbranch.
116       TBB = LastInst.getOperand(1).getMBB();
117       Cond.push_back(LastInst.getOperand(0));
118       return false;
119     }
120     // Otherwise, don't know what this is.
121     return true;
122   }
123 
124   // Get the instruction before it if it's a terminator.
125   MachineInstr &SecondLastInst = *I;
126 
127   // If there are three terminators, we don't know what sort of block this is.
128   if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
129     return true;
130 
131   // If the block ends with NVPTX::GOTO and NVPTX:CBranch, handle it.
132   if (SecondLastInst.getOpcode() == NVPTX::CBranch &&
133       LastInst.getOpcode() == NVPTX::GOTO) {
134     TBB = SecondLastInst.getOperand(1).getMBB();
135     Cond.push_back(SecondLastInst.getOperand(0));
136     FBB = LastInst.getOperand(0).getMBB();
137     return false;
138   }
139 
140   // If the block ends with two NVPTX:GOTOs, handle it.  The second one is not
141   // executed, so remove it.
142   if (SecondLastInst.getOpcode() == NVPTX::GOTO &&
143       LastInst.getOpcode() == NVPTX::GOTO) {
144     TBB = SecondLastInst.getOperand(0).getMBB();
145     I = LastInst;
146     if (AllowModify)
147       I->eraseFromParent();
148     return false;
149   }
150 
151   // Otherwise, can't handle this.
152   return true;
153 }
154 
removeBranch(MachineBasicBlock & MBB,int * BytesRemoved) const155 unsigned NVPTXInstrInfo::removeBranch(MachineBasicBlock &MBB,
156                                       int *BytesRemoved) const {
157   assert(!BytesRemoved && "code size not handled");
158   MachineBasicBlock::iterator I = MBB.end();
159   if (I == MBB.begin())
160     return 0;
161   --I;
162   if (I->getOpcode() != NVPTX::GOTO && I->getOpcode() != NVPTX::CBranch)
163     return 0;
164 
165   // Remove the branch.
166   I->eraseFromParent();
167 
168   I = MBB.end();
169 
170   if (I == MBB.begin())
171     return 1;
172   --I;
173   if (I->getOpcode() != NVPTX::CBranch)
174     return 1;
175 
176   // Remove the branch.
177   I->eraseFromParent();
178   return 2;
179 }
180 
insertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL,int * BytesAdded) const181 unsigned NVPTXInstrInfo::insertBranch(MachineBasicBlock &MBB,
182                                       MachineBasicBlock *TBB,
183                                       MachineBasicBlock *FBB,
184                                       ArrayRef<MachineOperand> Cond,
185                                       const DebugLoc &DL,
186                                       int *BytesAdded) const {
187   assert(!BytesAdded && "code size not handled");
188 
189   // Shouldn't be a fall through.
190   assert(TBB && "insertBranch must not be told to insert a fallthrough");
191   assert((Cond.size() == 1 || Cond.size() == 0) &&
192          "NVPTX branch conditions have two components!");
193 
194   // One-way branch.
195   if (!FBB) {
196     if (Cond.empty()) // Unconditional branch
197       BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(TBB);
198     else // Conditional branch
199       BuildMI(&MBB, DL, get(NVPTX::CBranch)).addReg(Cond[0].getReg())
200           .addMBB(TBB);
201     return 1;
202   }
203 
204   // Two-way Conditional Branch.
205   BuildMI(&MBB, DL, get(NVPTX::CBranch)).addReg(Cond[0].getReg()).addMBB(TBB);
206   BuildMI(&MBB, DL, get(NVPTX::GOTO)).addMBB(FBB);
207   return 2;
208 }
209