Skip to content

Commit 9fe3d58

Browse files
committed
[CIR][AMDGPU] Add basic ABI implementation of AMDGPU for CIR->LLVMIR
1 parent 635c88c commit 9fe3d58

File tree

1 file changed

+98
-3
lines changed
  • clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets

1 file changed

+98
-3
lines changed

clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/AMDGPU.cpp

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,15 @@ class AMDGPUABIInfo : public ABIInfo {
3434
AMDGPUABIInfo(LowerTypes &lt) : ABIInfo(lt) {}
3535

3636
private:
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

4248
class 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+
67162
std::unique_ptr<TargetLoweringInfo>
68163
createAMDGPUTargetLoweringInfo(LowerModule &lowerModule) {
69164
return std::make_unique<AMDGPUTargetLoweringInfo>(lowerModule.getTypes());

0 commit comments

Comments
 (0)