16
16
#define LLVM_CODEGEN_FASTISEL_H
17
17
18
18
#include " llvm/ADT/DenseMap.h"
19
+ #include " llvm/CodeGen/CallingConvLower.h"
19
20
#include " llvm/CodeGen/MachineBasicBlock.h"
21
+ #include " llvm/Target/TargetLowering.h"
22
+ #include " llvm/IR/CallingConv.h"
20
23
21
24
namespace llvm {
22
25
@@ -47,6 +50,144 @@ class Value;
47
50
// / This is a fast-path instruction selection class that generates poor code and
48
51
// / doesn't support illegal types or non-trivial lowering, but runs quickly.
49
52
class FastISel {
53
+ public:
54
+ struct ArgListEntry {
55
+ Value *Val;
56
+ Type *Ty;
57
+ bool isSExt : 1 ;
58
+ bool isZExt : 1 ;
59
+ bool isInReg : 1 ;
60
+ bool isSRet : 1 ;
61
+ bool isNest : 1 ;
62
+ bool isByVal : 1 ;
63
+ bool isInAlloca : 1 ;
64
+ bool isReturned : 1 ;
65
+ uint16_t Alignment;
66
+
67
+ ArgListEntry ()
68
+ : Val(nullptr ), Ty(nullptr ), isSExt(false ), isZExt(false ), isInReg(false ),
69
+ isSRet (false ), isNest(false ), isByVal(false ), isInAlloca(false ),
70
+ isReturned(false ), Alignment(0 ) { }
71
+
72
+ void setAttributes (ImmutableCallSite *CS, unsigned AttrIdx);
73
+ };
74
+ typedef std::vector<ArgListEntry> ArgListTy;
75
+
76
+ struct CallLoweringInfo {
77
+ Type *RetTy;
78
+ bool RetSExt : 1 ;
79
+ bool RetZExt : 1 ;
80
+ bool IsVarArg : 1 ;
81
+ bool IsInReg : 1 ;
82
+ bool DoesNotReturn : 1 ;
83
+ bool IsReturnValueUsed : 1 ;
84
+
85
+ // IsTailCall should be modified by implementations of
86
+ // FastLowerCall that perform tail call conversions.
87
+ bool IsTailCall;
88
+
89
+ unsigned NumFixedArgs;
90
+ CallingConv::ID CallConv;
91
+ const Value *Callee;
92
+ const char *SymName;
93
+ ArgListTy Args;
94
+ ImmutableCallSite *CS;
95
+ MachineInstr *Call;
96
+ unsigned ResultReg;
97
+ unsigned NumResultRegs;
98
+
99
+ SmallVector<Value *, 16 > OutVals;
100
+ SmallVector<ISD::ArgFlagsTy, 16 > OutFlags;
101
+ SmallVector<unsigned , 16 > OutRegs;
102
+ SmallVector<ISD::InputArg, 4 > Ins;
103
+ SmallVector<unsigned , 4 > InRegs;
104
+
105
+ CallLoweringInfo ()
106
+ : RetTy(nullptr ), RetSExt(false ), RetZExt(false ), IsVarArg(false ),
107
+ IsInReg (false ), DoesNotReturn(false ), IsReturnValueUsed(true ),
108
+ IsTailCall(false ), NumFixedArgs(-1 ), CallConv(CallingConv::C),
109
+ Callee(nullptr ), SymName(nullptr ), CS(nullptr ), Call(nullptr ),
110
+ ResultReg(0 ), NumResultRegs(0 )
111
+ {}
112
+
113
+ CallLoweringInfo &setCallee (Type *ResultTy, FunctionType *FuncTy,
114
+ const Value *Target, ArgListTy &&ArgsList,
115
+ ImmutableCallSite &Call) {
116
+ RetTy = ResultTy;
117
+ Callee = Target;
118
+
119
+ IsInReg = Call.paramHasAttr (0 , Attribute::InReg);
120
+ DoesNotReturn = Call.doesNotReturn ();
121
+ IsVarArg = FuncTy->isVarArg ();
122
+ IsReturnValueUsed = !Call.getInstruction ()->use_empty ();
123
+ RetSExt = Call.paramHasAttr (0 , Attribute::SExt);
124
+ RetZExt = Call.paramHasAttr (0 , Attribute::ZExt);
125
+
126
+ CallConv = Call.getCallingConv ();
127
+ NumFixedArgs = FuncTy->getNumParams ();
128
+ Args = std::move (ArgsList);
129
+
130
+ CS = &Call;
131
+
132
+ return *this ;
133
+ }
134
+
135
+ CallLoweringInfo &setCallee (Type *ResultTy, FunctionType *FuncTy,
136
+ const char *Target, ArgListTy &&ArgsList,
137
+ ImmutableCallSite &Call,
138
+ unsigned FixedArgs = ~0U ) {
139
+ RetTy = ResultTy;
140
+ Callee = Call.getCalledValue ();
141
+ SymName = Target;
142
+
143
+ IsInReg = Call.paramHasAttr (0 , Attribute::InReg);
144
+ DoesNotReturn = Call.doesNotReturn ();
145
+ IsVarArg = FuncTy->isVarArg ();
146
+ IsReturnValueUsed = !Call.getInstruction ()->use_empty ();
147
+ RetSExt = Call.paramHasAttr (0 , Attribute::SExt);
148
+ RetZExt = Call.paramHasAttr (0 , Attribute::ZExt);
149
+
150
+ CallConv = Call.getCallingConv ();
151
+ NumFixedArgs = (FixedArgs == ~0U ) ? FuncTy->getNumParams () : FixedArgs;
152
+ Args = std::move (ArgsList);
153
+
154
+ CS = &Call;
155
+
156
+ return *this ;
157
+ }
158
+
159
+ CallLoweringInfo &setCallee (CallingConv::ID CC, Type *ResultTy,
160
+ const Value *Target, ArgListTy &&ArgsList,
161
+ unsigned FixedArgs = ~0U ) {
162
+ RetTy = ResultTy;
163
+ Callee = Target;
164
+ CallConv = CC;
165
+ NumFixedArgs = (FixedArgs == ~0U ) ? Args.size () : FixedArgs;
166
+ Args = std::move (ArgsList);
167
+ return *this ;
168
+ }
169
+
170
+ CallLoweringInfo &setTailCall (bool Value = true ) {
171
+ IsTailCall = Value;
172
+ return *this ;
173
+ }
174
+
175
+ ArgListTy &getArgs () {
176
+ return Args;
177
+ }
178
+
179
+ void clearOuts () {
180
+ OutVals.clear ();
181
+ OutFlags.clear ();
182
+ OutRegs.clear ();
183
+ }
184
+
185
+ void clearIns () {
186
+ Ins.clear ();
187
+ InRegs.clear ();
188
+ }
189
+ };
190
+
50
191
protected:
51
192
DenseMap<const Value *, unsigned > LocalValueMap;
52
193
FunctionLoweringInfo &FuncInfo;
@@ -173,15 +314,18 @@ class FastISel {
173
314
// / process fails to select an instruction. This gives targets a chance to
174
315
// / emit code for anything that doesn't fit into FastISel's framework. It
175
316
// / returns true if it was successful.
176
- virtual bool
177
- TargetSelectInstruction (const Instruction *I) = 0 ;
317
+ virtual bool TargetSelectInstruction (const Instruction *I) = 0;
178
318
179
319
// / This method is called by target-independent code to do target specific
180
320
// / argument lowering. It returns true if it was successful.
181
321
virtual bool FastLowerArguments ();
182
322
183
- // / This method is called by target-independent code to do target specific
184
- // / intrinsic lowering. It returns true if it was successful.
323
+ // / \brief This method is called by target-independent code to do target
324
+ // / specific call lowering. It returns true if it was successful.
325
+ virtual bool FastLowerCall (CallLoweringInfo &CLI);
326
+
327
+ // / \brief This method is called by target-independent code to do target
328
+ // / specific intrinsic lowering. It returns true if it was successful.
185
329
virtual bool FastLowerIntrinsicCall (const IntrinsicInst *II);
186
330
187
331
// / This method is called by target-independent code to request that an
@@ -386,6 +530,9 @@ class FastISel {
386
530
// / \brief Create a machine mem operand from the given instruction.
387
531
MachineMemOperand *createMachineMemOperandFor (const Instruction *I) const ;
388
532
533
+ bool LowerCallTo (const CallInst *CI, const char *SymName, unsigned NumArgs);
534
+ bool LowerCallTo (CallLoweringInfo &CLI);
535
+
389
536
private:
390
537
bool SelectBinaryOp (const User *I, unsigned ISDOpcode);
391
538
@@ -394,7 +541,8 @@ class FastISel {
394
541
bool SelectGetElementPtr (const User *I);
395
542
396
543
bool SelectStackmap (const CallInst *I);
397
- bool SelectCall (const User *I);
544
+ bool LowerCall (const CallInst *I);
545
+ bool SelectCall (const User *Call);
398
546
bool SelectIntrinsicCall (const IntrinsicInst *II);
399
547
400
548
bool SelectBitCast (const User *I);
0 commit comments