Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 324b3fc

Browse files
committed
[FastISel] Add basic infrastructure to support a target-independent call lowering hook in FastISel. WIP
The infrastructure mimics the call lowering we have already in place for SelectionDAG, but with limitations. For example structure return demotion and non-simple types are not supported (yet). Currently every backend has its own implementation and duplicated code for call lowering. There is also no specified interface that could be called from target-independent code. The target-hook is opt-in and doesn't affect current implementations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212848 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent af6721b commit 324b3fc

File tree

2 files changed

+361
-7
lines changed

2 files changed

+361
-7
lines changed

include/llvm/CodeGen/FastISel.h

Lines changed: 153 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
#define LLVM_CODEGEN_FASTISEL_H
1717

1818
#include "llvm/ADT/DenseMap.h"
19+
#include "llvm/CodeGen/CallingConvLower.h"
1920
#include "llvm/CodeGen/MachineBasicBlock.h"
21+
#include "llvm/Target/TargetLowering.h"
22+
#include "llvm/IR/CallingConv.h"
2023

2124
namespace llvm {
2225

@@ -47,6 +50,144 @@ class Value;
4750
/// This is a fast-path instruction selection class that generates poor code and
4851
/// doesn't support illegal types or non-trivial lowering, but runs quickly.
4952
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+
50191
protected:
51192
DenseMap<const Value *, unsigned> LocalValueMap;
52193
FunctionLoweringInfo &FuncInfo;
@@ -173,15 +314,18 @@ class FastISel {
173314
/// process fails to select an instruction. This gives targets a chance to
174315
/// emit code for anything that doesn't fit into FastISel's framework. It
175316
/// returns true if it was successful.
176-
virtual bool
177-
TargetSelectInstruction(const Instruction *I) = 0;
317+
virtual bool TargetSelectInstruction(const Instruction *I) = 0;
178318

179319
/// This method is called by target-independent code to do target specific
180320
/// argument lowering. It returns true if it was successful.
181321
virtual bool FastLowerArguments();
182322

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.
185329
virtual bool FastLowerIntrinsicCall(const IntrinsicInst *II);
186330

187331
/// This method is called by target-independent code to request that an
@@ -386,6 +530,9 @@ class FastISel {
386530
/// \brief Create a machine mem operand from the given instruction.
387531
MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const;
388532

533+
bool LowerCallTo(const CallInst *CI, const char *SymName, unsigned NumArgs);
534+
bool LowerCallTo(CallLoweringInfo &CLI);
535+
389536
private:
390537
bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
391538

@@ -394,7 +541,8 @@ class FastISel {
394541
bool SelectGetElementPtr(const User *I);
395542

396543
bool SelectStackmap(const CallInst *I);
397-
bool SelectCall(const User *I);
544+
bool LowerCall(const CallInst *I);
545+
bool SelectCall(const User *Call);
398546
bool SelectIntrinsicCall(const IntrinsicInst *II);
399547

400548
bool SelectBitCast(const User *I);

0 commit comments

Comments
 (0)