@@ -34,9 +34,15 @@ class AMDGPUABIInfo : public ABIInfo {
3434 AMDGPUABIInfo (LowerTypes <) : ABIInfo(lt) {}
3535
3636private:
37- void computeInfo (LowerFunctionInfo &fi) const override {
38- llvm_unreachable (" NYI" );
39- }
37+ static const unsigned MaxNumRegsForArgsRet = 16 ;
38+
39+ unsigned numRegsForType (mlir::Type ty) const ;
40+
41+ ABIArgInfo classifyReturnType (mlir::Type ty) const ;
42+ ABIArgInfo classifyArgumentType (mlir::Type ty, bool Variadic,
43+ unsigned &NumRegsLeft) const ;
44+ ABIArgInfo classifyKernelArgumentType (mlir::Type ty) const ;
45+ void computeInfo (LowerFunctionInfo &fi) const override ;
4046};
4147
4248class AMDGPUTargetLoweringInfo : public TargetLoweringInfo {
@@ -63,7 +69,96 @@ class AMDGPUTargetLoweringInfo : public TargetLoweringInfo {
6369 }
6470};
6571
72+ // Estimate the number of registers the type will use
73+ unsigned AMDGPUABIInfo::numRegsForType (mlir::Type ty) const {
74+ uint64_t size = getContext ().getTypeSize (ty);
75+ return (size + 31 ) / 32 ;
76+ }
77+
78+ ABIArgInfo AMDGPUABIInfo::classifyReturnType (mlir::Type ty) const {
79+ if (isAggregateTypeForABI (ty)) {
80+ llvm_unreachable (
81+ " classifyReturnType for aggregate types is NYI for AMDGPU" );
82+ }
83+
84+ if (isPromotableIntegerTypeForABI (ty))
85+ return ABIArgInfo::getExtend (ty);
86+
87+ return ABIArgInfo::getDirect ();
88+ }
89+
90+ ABIArgInfo AMDGPUABIInfo::classifyArgumentType (mlir::Type ty, bool Variadic,
91+ unsigned &NumRegsLeft) const {
92+ assert (NumRegsLeft <= MaxNumRegsForArgsRet && " register estimate underflow" );
93+
94+ ty = useFirstFieldIfTransparentUnion (ty);
95+
96+ if (isAggregateTypeForABI (ty)) {
97+ llvm_unreachable (
98+ " classifyArgumentType for aggregate types is NYI for AMDGPU" );
99+ }
100+
101+ // Variadic arguments are always passed by-value in a single register or on
102+ // stack
103+ if (Variadic) {
104+ return ABIArgInfo::getDirect (/* T=*/ nullptr ,
105+ /* Offset=*/ 0 ,
106+ /* Padding=*/ nullptr ,
107+ /* CanBeFlattened=*/ false ,
108+ /* Align=*/ 0 );
109+ }
110+
111+ // Otherwise do default classification
112+ ABIArgInfo ArgInfo =
113+ (isPromotableIntegerTypeForABI (ty) ? ABIArgInfo::getExtend (ty)
114+ : ABIArgInfo::getDirect ());
115+
116+ // Track register usage
117+ if (!ArgInfo.isIndirect ()) {
118+ unsigned NumRegs = numRegsForType (ty);
119+ NumRegsLeft -= std::min (NumRegs, NumRegsLeft);
120+ }
121+
122+ return ArgInfo;
123+ }
124+
125+ ABIArgInfo AMDGPUABIInfo::classifyKernelArgumentType (mlir::Type ty) const {
126+ ty = useFirstFieldIfTransparentUnion (ty);
127+
128+ // Aggregate types are not yet supported
129+ if (isAggregateTypeForABI (ty)) {
130+ llvm_unreachable (" Aggregate types NYI for AMDGPU kernel arguments" );
131+ }
132+
133+ // If we set CanBeFlattened to true, CodeGen will expand the struct to its
134+ // individual elements, which confuses the Clover OpenCL backend; therefore we
135+ // have to set it to false here. Other args of getDirect() are just defaults.
136+ return ABIArgInfo::getDirect (/* T=*/ nullptr , /* Offset=*/ 0 , /* Padding=*/ nullptr ,
137+ /* CanBeFlattened=*/ false );
138+ }
139+
140+ void AMDGPUABIInfo::computeInfo (LowerFunctionInfo &fi) const {
141+ const unsigned CC = fi.getCallingConvention ();
142+
143+ if (!getCXXABI ().classifyReturnType (fi))
144+ fi.getReturnInfo () = classifyReturnType (fi.getReturnType ());
145+
146+ unsigned ArgumentIndex = 0 ;
147+ const unsigned NumFixedArguments = fi.getNumRequiredArgs ();
148+
149+ unsigned NumRegsLeft = MaxNumRegsForArgsRet;
150+ for (auto &arg : fi.arguments ()) {
151+ if (CC == llvm::CallingConv::AMDGPU_KERNEL) {
152+ arg.info = classifyKernelArgumentType (arg.type );
153+ } else {
154+ bool FixedArgument = ArgumentIndex++ < NumFixedArguments;
155+ arg.info = classifyArgumentType (arg.type , !FixedArgument, NumRegsLeft);
156+ }
157+ }
158+ }
159+
66160} // namespace
161+
67162std::unique_ptr<TargetLoweringInfo>
68163createAMDGPUTargetLoweringInfo (LowerModule &lowerModule) {
69164 return std::make_unique<AMDGPUTargetLoweringInfo>(lowerModule.getTypes ());
0 commit comments