blob: 865d8a88b8cc87ed5f3ce535613f4461c123b1f1 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- FastISel.h - Definition of the FastISel class ------------*- C++ -*-===//
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/// \file
11/// This file defines the FastISel class.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_FASTISEL_H
16#define LLVM_CODEGEN_FASTISEL_H
17
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/CodeGen/MachineBasicBlock.h"
22#include "llvm/CodeGen/TargetLowering.h"
23#include "llvm/IR/Attributes.h"
24#include "llvm/IR/CallSite.h"
25#include "llvm/IR/CallingConv.h"
26#include "llvm/IR/DebugLoc.h"
27#include "llvm/IR/DerivedTypes.h"
28#include "llvm/IR/InstrTypes.h"
29#include "llvm/IR/IntrinsicInst.h"
30#include "llvm/Support/MachineValueType.h"
31#include <algorithm>
32#include <cstdint>
33#include <utility>
34
35namespace llvm {
36
37class AllocaInst;
38class BasicBlock;
39class CallInst;
40class Constant;
41class ConstantFP;
42class DataLayout;
43class FunctionLoweringInfo;
44class LoadInst;
45class MachineConstantPool;
46class MachineFrameInfo;
47class MachineFunction;
48class MachineInstr;
49class MachineMemOperand;
50class MachineOperand;
51class MachineRegisterInfo;
52class MCContext;
53class MCInstrDesc;
54class MCSymbol;
55class TargetInstrInfo;
56class TargetLibraryInfo;
57class TargetMachine;
58class TargetRegisterClass;
59class TargetRegisterInfo;
60class Type;
61class User;
62class Value;
63
Andrew Scullcdfcccc2018-10-05 20:58:37 +010064/// This is a fast-path instruction selection class that generates poor
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010065/// code and doesn't support illegal types or non-trivial lowering, but runs
66/// quickly.
67class FastISel {
68public:
69 using ArgListEntry = TargetLoweringBase::ArgListEntry;
70 using ArgListTy = TargetLoweringBase::ArgListTy;
71 struct CallLoweringInfo {
72 Type *RetTy = nullptr;
73 bool RetSExt : 1;
74 bool RetZExt : 1;
75 bool IsVarArg : 1;
76 bool IsInReg : 1;
77 bool DoesNotReturn : 1;
78 bool IsReturnValueUsed : 1;
79 bool IsPatchPoint : 1;
80
Andrew Scullcdfcccc2018-10-05 20:58:37 +010081 // IsTailCall Should be modified by implementations of FastLowerCall
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010082 // that perform tail call conversions.
83 bool IsTailCall = false;
84
85 unsigned NumFixedArgs = -1;
86 CallingConv::ID CallConv = CallingConv::C;
87 const Value *Callee = nullptr;
88 MCSymbol *Symbol = nullptr;
89 ArgListTy Args;
90 ImmutableCallSite *CS = nullptr;
91 MachineInstr *Call = nullptr;
92 unsigned ResultReg = 0;
93 unsigned NumResultRegs = 0;
94
95 SmallVector<Value *, 16> OutVals;
96 SmallVector<ISD::ArgFlagsTy, 16> OutFlags;
97 SmallVector<unsigned, 16> OutRegs;
98 SmallVector<ISD::InputArg, 4> Ins;
99 SmallVector<unsigned, 4> InRegs;
100
101 CallLoweringInfo()
102 : RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
103 DoesNotReturn(false), IsReturnValueUsed(true), IsPatchPoint(false) {}
104
105 CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
106 const Value *Target, ArgListTy &&ArgsList,
107 ImmutableCallSite &Call) {
108 RetTy = ResultTy;
109 Callee = Target;
110
111 IsInReg = Call.hasRetAttr(Attribute::InReg);
112 DoesNotReturn = Call.doesNotReturn();
113 IsVarArg = FuncTy->isVarArg();
114 IsReturnValueUsed = !Call.getInstruction()->use_empty();
115 RetSExt = Call.hasRetAttr(Attribute::SExt);
116 RetZExt = Call.hasRetAttr(Attribute::ZExt);
117
118 CallConv = Call.getCallingConv();
119 Args = std::move(ArgsList);
120 NumFixedArgs = FuncTy->getNumParams();
121
122 CS = &Call;
123
124 return *this;
125 }
126
127 CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
128 MCSymbol *Target, ArgListTy &&ArgsList,
129 ImmutableCallSite &Call,
130 unsigned FixedArgs = ~0U) {
131 RetTy = ResultTy;
132 Callee = Call.getCalledValue();
133 Symbol = Target;
134
135 IsInReg = Call.hasRetAttr(Attribute::InReg);
136 DoesNotReturn = Call.doesNotReturn();
137 IsVarArg = FuncTy->isVarArg();
138 IsReturnValueUsed = !Call.getInstruction()->use_empty();
139 RetSExt = Call.hasRetAttr(Attribute::SExt);
140 RetZExt = Call.hasRetAttr(Attribute::ZExt);
141
142 CallConv = Call.getCallingConv();
143 Args = std::move(ArgsList);
144 NumFixedArgs = (FixedArgs == ~0U) ? FuncTy->getNumParams() : FixedArgs;
145
146 CS = &Call;
147
148 return *this;
149 }
150
151 CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultTy,
152 const Value *Target, ArgListTy &&ArgsList,
153 unsigned FixedArgs = ~0U) {
154 RetTy = ResultTy;
155 Callee = Target;
156 CallConv = CC;
157 Args = std::move(ArgsList);
158 NumFixedArgs = (FixedArgs == ~0U) ? Args.size() : FixedArgs;
159 return *this;
160 }
161
162 CallLoweringInfo &setCallee(const DataLayout &DL, MCContext &Ctx,
163 CallingConv::ID CC, Type *ResultTy,
164 StringRef Target, ArgListTy &&ArgsList,
165 unsigned FixedArgs = ~0U);
166
167 CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultTy,
168 MCSymbol *Target, ArgListTy &&ArgsList,
169 unsigned FixedArgs = ~0U) {
170 RetTy = ResultTy;
171 Symbol = Target;
172 CallConv = CC;
173 Args = std::move(ArgsList);
174 NumFixedArgs = (FixedArgs == ~0U) ? Args.size() : FixedArgs;
175 return *this;
176 }
177
178 CallLoweringInfo &setTailCall(bool Value = true) {
179 IsTailCall = Value;
180 return *this;
181 }
182
183 CallLoweringInfo &setIsPatchPoint(bool Value = true) {
184 IsPatchPoint = Value;
185 return *this;
186 }
187
188 ArgListTy &getArgs() { return Args; }
189
190 void clearOuts() {
191 OutVals.clear();
192 OutFlags.clear();
193 OutRegs.clear();
194 }
195
196 void clearIns() {
197 Ins.clear();
198 InRegs.clear();
199 }
200 };
201
202protected:
203 DenseMap<const Value *, unsigned> LocalValueMap;
204 FunctionLoweringInfo &FuncInfo;
205 MachineFunction *MF;
206 MachineRegisterInfo &MRI;
207 MachineFrameInfo &MFI;
208 MachineConstantPool &MCP;
209 DebugLoc DbgLoc;
210 const TargetMachine &TM;
211 const DataLayout &DL;
212 const TargetInstrInfo &TII;
213 const TargetLowering &TLI;
214 const TargetRegisterInfo &TRI;
215 const TargetLibraryInfo *LibInfo;
216 bool SkipTargetIndependentISel;
217
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100218 /// The position of the last instruction for materializing constants
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100219 /// for use in the current block. It resets to EmitStartPt when it makes sense
220 /// (for example, it's usually profitable to avoid function calls between the
221 /// definition and the use)
222 MachineInstr *LastLocalValue;
223
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100224 /// The top most instruction in the current block that is allowed for
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100225 /// emitting local variables. LastLocalValue resets to EmitStartPt when it
226 /// makes sense (for example, on function calls)
227 MachineInstr *EmitStartPt;
228
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100229 /// Last local value flush point. On a subsequent flush, no local value will
230 /// sink past this point.
231 MachineBasicBlock::iterator LastFlushPoint;
232
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100233public:
234 virtual ~FastISel();
235
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100236 /// Return the position of the last instruction emitted for
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100237 /// materializing constants for use in the current block.
238 MachineInstr *getLastLocalValue() { return LastLocalValue; }
239
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100240 /// Update the position of the last instruction emitted for
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100241 /// materializing constants for use in the current block.
242 void setLastLocalValue(MachineInstr *I) {
243 EmitStartPt = I;
244 LastLocalValue = I;
245 }
246
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100247 /// Set the current block to which generated machine instructions will
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100248 /// be appended.
249 void startNewBlock();
250
251 /// Flush the local value map and sink local values if possible.
252 void finishBasicBlock();
253
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100254 /// Return current debug location information.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100255 DebugLoc getCurDebugLoc() const { return DbgLoc; }
256
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100257 /// Do "fast" instruction selection for function arguments and append
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100258 /// the machine instructions to the current block. Returns true when
259 /// successful.
260 bool lowerArguments();
261
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100262 /// Do "fast" instruction selection for the given LLVM IR instruction
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100263 /// and append the generated machine instructions to the current block.
264 /// Returns true if selection was successful.
265 bool selectInstruction(const Instruction *I);
266
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100267 /// Do "fast" instruction selection for the given LLVM IR operator
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100268 /// (Instruction or ConstantExpr), and append generated machine instructions
269 /// to the current block. Return true if selection was successful.
270 bool selectOperator(const User *I, unsigned Opcode);
271
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100272 /// Create a virtual register and arrange for it to be assigned the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100273 /// value for the given LLVM value.
274 unsigned getRegForValue(const Value *V);
275
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100276 /// Look up the value to see if its value is already cached in a
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100277 /// register. It may be defined by instructions across blocks or defined
278 /// locally.
279 unsigned lookUpRegForValue(const Value *V);
280
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100281 /// This is a wrapper around getRegForValue that also takes care of
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100282 /// truncating or sign-extending the given getelementptr index value.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100283 std::pair<unsigned, bool> getRegForGEPIndex(const Value *Idx);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100284
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100285 /// We're checking to see if we can fold \p LI into \p FoldInst. Note
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100286 /// that we could have a sequence where multiple LLVM IR instructions are
287 /// folded into the same machineinstr. For example we could have:
288 ///
289 /// A: x = load i32 *P
290 /// B: y = icmp A, 42
291 /// C: br y, ...
292 ///
293 /// In this scenario, \p LI is "A", and \p FoldInst is "C". We know about "B"
294 /// (and any other folded instructions) because it is between A and C.
295 ///
296 /// If we succeed folding, return true.
297 bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst);
298
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100299 /// The specified machine instr operand is a vreg, and that vreg is
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100300 /// being provided by the specified load instruction. If possible, try to
301 /// fold the load as an operand to the instruction, returning true if
302 /// possible.
303 ///
304 /// This method should be implemented by targets.
305 virtual bool tryToFoldLoadIntoMI(MachineInstr * /*MI*/, unsigned /*OpNo*/,
306 const LoadInst * /*LI*/) {
307 return false;
308 }
309
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100310 /// Reset InsertPt to prepare for inserting instructions into the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100311 /// current block.
312 void recomputeInsertPt();
313
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100314 /// Remove all dead instructions between the I and E.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100315 void removeDeadCode(MachineBasicBlock::iterator I,
316 MachineBasicBlock::iterator E);
317
318 struct SavePoint {
319 MachineBasicBlock::iterator InsertPt;
320 DebugLoc DL;
321 };
322
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100323 /// Prepare InsertPt to begin inserting instructions into the local
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100324 /// value area and return the old insert position.
325 SavePoint enterLocalValueArea();
326
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100327 /// Reset InsertPt to the given old insert position.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100328 void leaveLocalValueArea(SavePoint Old);
329
330protected:
331 explicit FastISel(FunctionLoweringInfo &FuncInfo,
332 const TargetLibraryInfo *LibInfo,
333 bool SkipTargetIndependentISel = false);
334
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100335 /// This method is called by target-independent code when the normal
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100336 /// FastISel process fails to select an instruction. This gives targets a
337 /// chance to emit code for anything that doesn't fit into FastISel's
338 /// framework. It returns true if it was successful.
339 virtual bool fastSelectInstruction(const Instruction *I) = 0;
340
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100341 /// This method is called by target-independent code to do target-
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100342 /// specific argument lowering. It returns true if it was successful.
343 virtual bool fastLowerArguments();
344
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100345 /// This method is called by target-independent code to do target-
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100346 /// specific call lowering. It returns true if it was successful.
347 virtual bool fastLowerCall(CallLoweringInfo &CLI);
348
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100349 /// This method is called by target-independent code to do target-
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100350 /// specific intrinsic lowering. It returns true if it was successful.
351 virtual bool fastLowerIntrinsicCall(const IntrinsicInst *II);
352
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100353 /// This method is called by target-independent code to request that an
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100354 /// instruction with the given type and opcode be emitted.
355 virtual unsigned fastEmit_(MVT VT, MVT RetVT, unsigned Opcode);
356
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100357 /// This method is called by target-independent code to request that an
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100358 /// instruction with the given type, opcode, and register operand be emitted.
359 virtual unsigned fastEmit_r(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
360 bool Op0IsKill);
361
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100362 /// This method is called by target-independent code to request that an
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100363 /// instruction with the given type, opcode, and register operands be emitted.
364 virtual unsigned fastEmit_rr(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
365 bool Op0IsKill, unsigned Op1, bool Op1IsKill);
366
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100367 /// This method is called by target-independent code to request that an
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100368 /// instruction with the given type, opcode, and register and immediate
369 /// operands be emitted.
370 virtual unsigned fastEmit_ri(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
371 bool Op0IsKill, uint64_t Imm);
372
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100373 /// This method is a wrapper of fastEmit_ri.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100374 ///
375 /// It first tries to emit an instruction with an immediate operand using
376 /// fastEmit_ri. If that fails, it materializes the immediate into a register
377 /// and try fastEmit_rr instead.
378 unsigned fastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0, bool Op0IsKill,
379 uint64_t Imm, MVT ImmType);
380
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100381 /// This method is called by target-independent code to request that an
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100382 /// instruction with the given type, opcode, and immediate operand be emitted.
383 virtual unsigned fastEmit_i(MVT VT, MVT RetVT, unsigned Opcode, uint64_t Imm);
384
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100385 /// This method is called by target-independent code to request that an
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100386 /// instruction with the given type, opcode, and floating-point immediate
387 /// operand be emitted.
388 virtual unsigned fastEmit_f(MVT VT, MVT RetVT, unsigned Opcode,
389 const ConstantFP *FPImm);
390
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100391 /// Emit a MachineInstr with no operands and a result register in the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100392 /// given register class.
393 unsigned fastEmitInst_(unsigned MachineInstOpcode,
394 const TargetRegisterClass *RC);
395
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100396 /// Emit a MachineInstr with one register operand and a result register
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100397 /// in the given register class.
398 unsigned fastEmitInst_r(unsigned MachineInstOpcode,
399 const TargetRegisterClass *RC, unsigned Op0,
400 bool Op0IsKill);
401
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100402 /// Emit a MachineInstr with two register operands and a result
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100403 /// register in the given register class.
404 unsigned fastEmitInst_rr(unsigned MachineInstOpcode,
405 const TargetRegisterClass *RC, unsigned Op0,
406 bool Op0IsKill, unsigned Op1, bool Op1IsKill);
407
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100408 /// Emit a MachineInstr with three register operands and a result
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100409 /// register in the given register class.
410 unsigned fastEmitInst_rrr(unsigned MachineInstOpcode,
411 const TargetRegisterClass *RC, unsigned Op0,
412 bool Op0IsKill, unsigned Op1, bool Op1IsKill,
413 unsigned Op2, bool Op2IsKill);
414
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100415 /// Emit a MachineInstr with a register operand, an immediate, and a
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100416 /// result register in the given register class.
417 unsigned fastEmitInst_ri(unsigned MachineInstOpcode,
418 const TargetRegisterClass *RC, unsigned Op0,
419 bool Op0IsKill, uint64_t Imm);
420
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100421 /// Emit a MachineInstr with one register operand and two immediate
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100422 /// operands.
423 unsigned fastEmitInst_rii(unsigned MachineInstOpcode,
424 const TargetRegisterClass *RC, unsigned Op0,
425 bool Op0IsKill, uint64_t Imm1, uint64_t Imm2);
426
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100427 /// Emit a MachineInstr with a floating point immediate, and a result
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100428 /// register in the given register class.
429 unsigned fastEmitInst_f(unsigned MachineInstOpcode,
430 const TargetRegisterClass *RC,
431 const ConstantFP *FPImm);
432
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100433 /// Emit a MachineInstr with two register operands, an immediate, and a
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100434 /// result register in the given register class.
435 unsigned fastEmitInst_rri(unsigned MachineInstOpcode,
436 const TargetRegisterClass *RC, unsigned Op0,
437 bool Op0IsKill, unsigned Op1, bool Op1IsKill,
438 uint64_t Imm);
439
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100440 /// Emit a MachineInstr with a single immediate operand, and a result
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100441 /// register in the given register class.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100442 unsigned fastEmitInst_i(unsigned MachineInstOpcode,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100443 const TargetRegisterClass *RC, uint64_t Imm);
444
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100445 /// Emit a MachineInstr for an extract_subreg from a specified index of
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100446 /// a superregister to a specified type.
447 unsigned fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, bool Op0IsKill,
448 uint32_t Idx);
449
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100450 /// Emit MachineInstrs to compute the value of Op with all but the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100451 /// least significant bit set to zero.
452 unsigned fastEmitZExtFromI1(MVT VT, unsigned Op0, bool Op0IsKill);
453
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100454 /// Emit an unconditional branch to the given block, unless it is the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100455 /// immediate (fall-through) successor, and update the CFG.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100456 void fastEmitBranch(MachineBasicBlock *MSucc, const DebugLoc &DbgLoc);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100457
458 /// Emit an unconditional branch to \p FalseMBB, obtains the branch weight
459 /// and adds TrueMBB and FalseMBB to the successor list.
460 void finishCondBranch(const BasicBlock *BranchBB, MachineBasicBlock *TrueMBB,
461 MachineBasicBlock *FalseMBB);
462
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100463 /// Update the value map to include the new mapping for this
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100464 /// instruction, or insert an extra copy to get the result in a previous
465 /// determined register.
466 ///
467 /// NOTE: This is only necessary because we might select a block that uses a
468 /// value before we select the block that defines the value. It might be
469 /// possible to fix this by selecting blocks in reverse postorder.
470 void updateValueMap(const Value *I, unsigned Reg, unsigned NumRegs = 1);
471
472 unsigned createResultReg(const TargetRegisterClass *RC);
473
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100474 /// Try to constrain Op so that it is usable by argument OpNum of the
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100475 /// provided MCInstrDesc. If this fails, create a new virtual register in the
476 /// correct class and COPY the value there.
477 unsigned constrainOperandRegClass(const MCInstrDesc &II, unsigned Op,
478 unsigned OpNum);
479
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100480 /// Emit a constant in a register using target-specific logic, such as
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100481 /// constant pool loads.
482 virtual unsigned fastMaterializeConstant(const Constant *C) { return 0; }
483
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100484 /// Emit an alloca address in a register using target-specific logic.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100485 virtual unsigned fastMaterializeAlloca(const AllocaInst *C) { return 0; }
486
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100487 /// Emit the floating-point constant +0.0 in a register using target-
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100488 /// specific logic.
489 virtual unsigned fastMaterializeFloatZero(const ConstantFP *CF) {
490 return 0;
491 }
492
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100493 /// Check if \c Add is an add that can be safely folded into \c GEP.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100494 ///
495 /// \c Add can be folded into \c GEP if:
496 /// - \c Add is an add,
497 /// - \c Add's size matches \c GEP's,
498 /// - \c Add is in the same basic block as \c GEP, and
499 /// - \c Add has a constant operand.
500 bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
501
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100502 /// Test whether the given value has exactly one use.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100503 bool hasTrivialKill(const Value *V);
504
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100505 /// Create a machine mem operand from the given instruction.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100506 MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const;
507
508 CmpInst::Predicate optimizeCmpPredicate(const CmpInst *CI) const;
509
510 bool lowerCallTo(const CallInst *CI, MCSymbol *Symbol, unsigned NumArgs);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100511 bool lowerCallTo(const CallInst *CI, const char *SymName,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100512 unsigned NumArgs);
513 bool lowerCallTo(CallLoweringInfo &CLI);
514
515 bool isCommutativeIntrinsic(IntrinsicInst const *II) {
516 switch (II->getIntrinsicID()) {
517 case Intrinsic::sadd_with_overflow:
518 case Intrinsic::uadd_with_overflow:
519 case Intrinsic::smul_with_overflow:
520 case Intrinsic::umul_with_overflow:
521 return true;
522 default:
523 return false;
524 }
525 }
526
527 bool lowerCall(const CallInst *I);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100528 /// Select and emit code for a binary operator instruction, which has
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100529 /// an opcode which directly corresponds to the given ISD opcode.
530 bool selectBinaryOp(const User *I, unsigned ISDOpcode);
531 bool selectFNeg(const User *I);
532 bool selectGetElementPtr(const User *I);
533 bool selectStackmap(const CallInst *I);
534 bool selectPatchpoint(const CallInst *I);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100535 bool selectCall(const User *I);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100536 bool selectIntrinsicCall(const IntrinsicInst *II);
537 bool selectBitCast(const User *I);
538 bool selectCast(const User *I, unsigned Opcode);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100539 bool selectExtractValue(const User *U);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100540 bool selectInsertValue(const User *I);
541 bool selectXRayCustomEvent(const CallInst *II);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100542 bool selectXRayTypedEvent(const CallInst *II);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100543
544private:
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100545 /// Handle PHI nodes in successor blocks.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100546 ///
547 /// Emit code to ensure constants are copied into registers when needed.
548 /// Remember the virtual registers that need to be added to the Machine PHI
549 /// nodes as input. We cannot just directly add them, because expansion might
550 /// result in multiple MBB's for one BB. As such, the start of the BB might
551 /// correspond to a different MBB than the end.
552 bool handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
553
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100554 /// Helper for materializeRegForValue to materialize a constant in a
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100555 /// target-independent way.
556 unsigned materializeConstant(const Value *V, MVT VT);
557
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100558 /// Helper for getRegForVale. This function is called when the value
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100559 /// isn't already available in a register and must be materialized with new
560 /// instructions.
561 unsigned materializeRegForValue(const Value *V, MVT VT);
562
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100563 /// Clears LocalValueMap and moves the area for the new local variables
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100564 /// to the beginning of the block. It helps to avoid spilling cached variables
565 /// across heavy instructions like calls.
566 void flushLocalValueMap();
567
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100568 /// Removes dead local value instructions after SavedLastLocalvalue.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100569 void removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue);
570
571 struct InstOrderMap {
572 DenseMap<MachineInstr *, unsigned> Orders;
573 MachineInstr *FirstTerminator = nullptr;
574 unsigned FirstTerminatorOrder = std::numeric_limits<unsigned>::max();
575
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100576 void initialize(MachineBasicBlock *MBB,
577 MachineBasicBlock::iterator LastFlushPoint);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100578 };
579
580 /// Sinks the local value materialization instruction LocalMI to its first use
581 /// in the basic block, or deletes it if it is not used.
582 void sinkLocalValueMaterialization(MachineInstr &LocalMI, unsigned DefReg,
583 InstOrderMap &OrderMap);
584
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100585 /// Insertion point before trying to select the current instruction.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100586 MachineBasicBlock::iterator SavedInsertPt;
587
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100588 /// Add a stackmap or patchpoint intrinsic call's live variable
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100589 /// operands to a stackmap or patchpoint machine instruction.
590 bool addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,
591 const CallInst *CI, unsigned StartIdx);
592 bool lowerCallOperands(const CallInst *CI, unsigned ArgIdx, unsigned NumArgs,
593 const Value *Callee, bool ForceRetVoidTy,
594 CallLoweringInfo &CLI);
595};
596
597} // end namespace llvm
598
599#endif // LLVM_CODEGEN_FASTISEL_H