Skip to content

Commit 49b79d5

Browse files
authored
[CIR][NFC] Remove ABI handling from CIRGen call handling (#139159)
We want to defer ABI handling until we lower to the LLVM dialect. Some code was in place to calculate ABI handling, but the computed effects weren't actually used. This corresponds to the changes made in llvm/clangir#1604
1 parent 24db9b5 commit 49b79d5

File tree

7 files changed

+45
-206
lines changed

7 files changed

+45
-206
lines changed

clang/lib/CIR/CodeGen/ABIInfo.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ class ABIInfo {
2323
ABIInfo(CIRGenTypes &cgt) : cgt(cgt) {}
2424

2525
virtual ~ABIInfo();
26-
27-
virtual void computeInfo(CIRGenFunctionInfo &funcInfo) const = 0;
2826
};
2927

3028
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 42 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -39,86 +39,6 @@ CIRGenFunctionInfo::create(CanQualType resultType,
3939
return fi;
4040
}
4141

42-
namespace {
43-
44-
/// Encapsulates information about the way function arguments from
45-
/// CIRGenFunctionInfo should be passed to actual CIR function.
46-
class ClangToCIRArgMapping {
47-
static constexpr unsigned invalidIndex = ~0U;
48-
unsigned totalNumCIRArgs;
49-
50-
/// Arguments of CIR function corresponding to single Clang argument.
51-
struct CIRArgs {
52-
// Argument is expanded to CIR arguments at positions
53-
// [FirstArgIndex, FirstArgIndex + NumberOfArgs).
54-
unsigned firstArgIndex = 0;
55-
unsigned numberOfArgs = 0;
56-
57-
CIRArgs() : firstArgIndex(invalidIndex), numberOfArgs(0) {}
58-
};
59-
60-
SmallVector<CIRArgs, 8> argInfo;
61-
62-
public:
63-
ClangToCIRArgMapping(const ASTContext &astContext,
64-
const CIRGenFunctionInfo &funcInfo)
65-
: totalNumCIRArgs(0), argInfo(funcInfo.arg_size()) {
66-
unsigned cirArgNo = 0;
67-
68-
assert(!cir::MissingFeatures::opCallABIIndirectArg());
69-
70-
unsigned argNo = 0;
71-
for (const CIRGenFunctionInfoArgInfo &i : funcInfo.arguments()) {
72-
// Collect data about CIR arguments corresponding to Clang argument ArgNo.
73-
CIRArgs &cirArgs = argInfo[argNo];
74-
75-
assert(!cir::MissingFeatures::opCallPaddingArgs());
76-
77-
switch (i.info.getKind()) {
78-
default:
79-
assert(!cir::MissingFeatures::abiArgInfo());
80-
// For now we just fall through. More argument kinds will be added later
81-
// as the upstreaming proceeds.
82-
[[fallthrough]];
83-
case cir::ABIArgInfo::Direct:
84-
// Postpone splitting structs into elements since this makes it way
85-
// more complicated for analysis to obtain information on the original
86-
// arguments.
87-
//
88-
// TODO(cir): a LLVM lowering prepare pass should break this down into
89-
// the appropriated pieces.
90-
assert(!cir::MissingFeatures::opCallABIExtendArg());
91-
cirArgs.numberOfArgs = 1;
92-
break;
93-
}
94-
95-
if (cirArgs.numberOfArgs > 0) {
96-
cirArgs.firstArgIndex = cirArgNo;
97-
cirArgNo += cirArgs.numberOfArgs;
98-
}
99-
100-
++argNo;
101-
}
102-
103-
assert(argNo == argInfo.size());
104-
assert(!cir::MissingFeatures::opCallInAlloca());
105-
106-
totalNumCIRArgs = cirArgNo;
107-
}
108-
109-
unsigned totalCIRArgs() const { return totalNumCIRArgs; }
110-
111-
/// Returns index of first CIR argument corresponding to argNo, and their
112-
/// quantity.
113-
std::pair<unsigned, unsigned> getCIRArgs(unsigned argNo) const {
114-
assert(argNo < argInfo.size());
115-
return std::make_pair(argInfo[argNo].firstArgIndex,
116-
argInfo[argNo].numberOfArgs);
117-
}
118-
};
119-
120-
} // namespace
121-
12242
CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
12343
assert(!cir::MissingFeatures::opCallVirtual());
12444
return *this;
@@ -175,56 +95,38 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
17595
cir::CIRCallOpInterface *callOp,
17696
mlir::Location loc) {
17797
QualType retTy = funcInfo.getReturnType();
178-
const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo();
17998

180-
ClangToCIRArgMapping cirFuncArgs(cgm.getASTContext(), funcInfo);
181-
SmallVector<mlir::Value, 16> cirCallArgs(cirFuncArgs.totalCIRArgs());
99+
SmallVector<mlir::Value, 16> cirCallArgs(args.size());
182100

183101
assert(!cir::MissingFeatures::emitLifetimeMarkers());
184102

185103
// Translate all of the arguments as necessary to match the CIR lowering.
186-
assert(funcInfo.arg_size() == args.size() &&
187-
"Mismatch between function signature & arguments.");
188-
unsigned argNo = 0;
189-
for (const auto &[arg, argInfo] : llvm::zip(args, funcInfo.arguments())) {
104+
for (auto [argNo, arg, argInfo] :
105+
llvm::enumerate(args, funcInfo.arguments())) {
190106
// Insert a padding argument to ensure proper alignment.
191107
assert(!cir::MissingFeatures::opCallPaddingArgs());
192108

193-
unsigned firstCIRArg;
194-
unsigned numCIRArgs;
195-
std::tie(firstCIRArg, numCIRArgs) = cirFuncArgs.getCIRArgs(argNo);
196-
197-
switch (argInfo.info.getKind()) {
198-
case cir::ABIArgInfo::Direct: {
199-
if (!mlir::isa<cir::RecordType>(argInfo.info.getCoerceToType()) &&
200-
argInfo.info.getCoerceToType() == convertType(argInfo.type) &&
201-
argInfo.info.getDirectOffset() == 0) {
202-
assert(numCIRArgs == 1);
203-
assert(!cir::MissingFeatures::opCallAggregateArgs());
204-
mlir::Value v = arg.getKnownRValue().getScalarVal();
205-
206-
assert(!cir::MissingFeatures::opCallExtParameterInfo());
207-
208-
// We might have to widen integers, but we should never truncate.
209-
assert(!cir::MissingFeatures::opCallWidenArg());
210-
211-
// If the argument doesn't match, perform a bitcast to coerce it. This
212-
// can happen due to trivial type mismatches.
213-
assert(!cir::MissingFeatures::opCallBitcastArg());
214-
215-
cirCallArgs[firstCIRArg] = v;
216-
break;
217-
}
218-
109+
mlir::Type argType = convertType(argInfo.type);
110+
if (!mlir::isa<cir::RecordType>(argType)) {
111+
mlir::Value v;
112+
if (arg.isAggregate())
113+
cgm.errorNYI(loc, "emitCall: aggregate call argument");
114+
v = arg.getKnownRValue().getScalarVal();
115+
116+
// We might have to widen integers, but we should never truncate.
117+
if (argType != v.getType() && mlir::isa<cir::IntType>(v.getType()))
118+
cgm.errorNYI(loc, "emitCall: widening integer call argument");
119+
120+
// If the argument doesn't match, perform a bitcast to coerce it. This
121+
// can happen due to trivial type mismatches.
122+
// TODO(cir): When getFunctionType is added, assert that this isn't
123+
// needed.
124+
assert(!cir::MissingFeatures::opCallBitcastArg());
125+
cirCallArgs[argNo] = v;
126+
} else {
219127
assert(!cir::MissingFeatures::opCallAggregateArgs());
220128
cgm.errorNYI("emitCall: aggregate function call argument");
221-
break;
222-
}
223-
default:
224-
cgm.errorNYI("unsupported argument kind");
225129
}
226-
227-
++argNo;
228130
}
229131

230132
const CIRGenCallee &concreteCallee = callee.prepareConcreteCallee(*this);
@@ -256,45 +158,31 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
256158
assert(!cir::MissingFeatures::opCallMustTail());
257159
assert(!cir::MissingFeatures::opCallReturn());
258160

259-
switch (retInfo.getKind()) {
260-
case cir::ABIArgInfo::Direct: {
261-
mlir::Type retCIRTy = convertType(retTy);
262-
if (retInfo.getCoerceToType() == retCIRTy &&
263-
retInfo.getDirectOffset() == 0) {
264-
switch (getEvaluationKind(retTy)) {
265-
case cir::TEK_Scalar: {
266-
mlir::ResultRange results = theCall->getOpResults();
267-
assert(results.size() == 1 && "unexpected number of returns");
268-
269-
// If the argument doesn't match, perform a bitcast to coerce it. This
270-
// can happen due to trivial type mismatches.
271-
if (results[0].getType() != retCIRTy)
272-
cgm.errorNYI(loc, "bitcast on function return value");
273-
274-
mlir::Region *region = builder.getBlock()->getParent();
275-
if (region != theCall->getParentRegion())
276-
cgm.errorNYI(loc, "function calls with cleanup");
277-
278-
return RValue::get(results[0]);
279-
}
280-
case cir::TEK_Complex:
281-
case cir::TEK_Aggregate:
282-
cgm.errorNYI(loc,
283-
"unsupported evaluation kind of function call result");
284-
return getUndefRValue(retTy);
285-
}
286-
llvm_unreachable("Invalid evaluation kind");
287-
}
288-
cgm.errorNYI(loc, "unsupported function call form");
161+
mlir::Type retCIRTy = convertType(retTy);
162+
if (isa<cir::VoidType>(retCIRTy))
289163
return getUndefRValue(retTy);
164+
switch (getEvaluationKind(retTy)) {
165+
case cir::TEK_Scalar: {
166+
mlir::ResultRange results = theCall->getOpResults();
167+
assert(results.size() == 1 && "unexpected number of returns");
168+
169+
// If the argument doesn't match, perform a bitcast to coerce it. This
170+
// can happen due to trivial type mismatches.
171+
if (results[0].getType() != retCIRTy)
172+
cgm.errorNYI(loc, "bitcast on function return value");
173+
174+
mlir::Region *region = builder.getBlock()->getParent();
175+
if (region != theCall->getParentRegion())
176+
cgm.errorNYI(loc, "function calls with cleanup");
177+
178+
return RValue::get(results[0]);
290179
}
291-
case cir::ABIArgInfo::Ignore:
292-
// If we are ignoring an argument that had a result, make sure to construct
293-
// the appropriate return value for our caller.
180+
case cir::TEK_Complex:
181+
case cir::TEK_Aggregate:
182+
cgm.errorNYI(loc, "unsupported evaluation kind of function call result");
294183
return getUndefRValue(retTy);
295184
}
296-
297-
llvm_unreachable("Invalid return info kind");
185+
llvm_unreachable("Invalid evaluation kind");
298186
}
299187

300188
void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,

clang/lib/CIR/CodeGen/CIRGenCall.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ struct CallArg {
102102
assert(!hasLV && !isUsed);
103103
return rv;
104104
}
105+
106+
bool isAggregate() const { return hasLV || rv.isAggregate(); }
105107
};
106108

107109
class CallArgList : public llvm::SmallVector<CallArg, 8> {

clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@
1616
#define LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H
1717

1818
#include "clang/AST/CanonicalType.h"
19-
#include "clang/CIR/ABIArgInfo.h"
2019
#include "llvm/ADT/FoldingSet.h"
2120
#include "llvm/Support/TrailingObjects.h"
2221

2322
namespace clang::CIRGen {
2423

2524
struct CIRGenFunctionInfoArgInfo {
2625
CanQualType type;
27-
cir::ABIArgInfo info;
2826
};
2927

3028
class CIRGenFunctionInfo final
@@ -77,11 +75,6 @@ class CIRGenFunctionInfo final
7775
unsigned arg_size() const { return numArgs; }
7876

7977
CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
80-
81-
cir::ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
82-
const cir::ABIArgInfo &getReturnInfo() const {
83-
return getArgsBuffer()[0].info;
84-
}
8578
};
8679

8780
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -538,27 +538,5 @@ const CIRGenFunctionInfo &CIRGenTypes::arrangeCIRFunctionInfo(
538538
fi = CIRGenFunctionInfo::create(returnType, argTypes);
539539
functionInfos.InsertNode(fi, insertPos);
540540

541-
bool inserted = functionsBeingProcessed.insert(fi).second;
542-
(void)inserted;
543-
assert(inserted && "Are functions being processed recursively?");
544-
545-
assert(!cir::MissingFeatures::opCallCallConv());
546-
getABIInfo().computeInfo(*fi);
547-
548-
// Loop over all of the computed argument and return value info. If any of
549-
// them are direct or extend without a specified coerce type, specify the
550-
// default now.
551-
cir::ABIArgInfo &retInfo = fi->getReturnInfo();
552-
if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr)
553-
retInfo.setCoerceToType(convertType(fi->getReturnType()));
554-
555-
for (CIRGenFunctionInfoArgInfo &i : fi->arguments())
556-
if (i.info.canHaveCoerceToType() && i.info.getCoerceToType() == nullptr)
557-
i.info.setCoerceToType(convertType(i.type));
558-
559-
bool erased = functionsBeingProcessed.erase(fi);
560-
(void)erased;
561-
assert(erased && "Not in set?");
562-
563541
return *fi;
564542
}

clang/lib/CIR/CodeGen/CIRGenValue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class RValue {
4343

4444
public:
4545
bool isScalar() const { return v1.getInt() == Scalar; }
46+
bool isAggregate() const { return v1.getInt() == Aggregate; }
4647

4748
/// Return the mlir::Value of this scalar value.
4849
mlir::Value getScalarVal() const {

clang/lib/CIR/CodeGen/TargetInfo.cpp

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ namespace {
1616
class X8664ABIInfo : public ABIInfo {
1717
public:
1818
X8664ABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
19-
20-
void computeInfo(CIRGenFunctionInfo &funcInfo) const override;
2119
};
2220

2321
class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
@@ -28,25 +26,6 @@ class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
2826

2927
} // namespace
3028

31-
void X8664ABIInfo::computeInfo(CIRGenFunctionInfo &funcInfo) const {
32-
// Top level CIR has unlimited arguments and return types. Lowering for ABI
33-
// specific concerns should happen during a lowering phase. Assume everything
34-
// is direct for now.
35-
for (CIRGenFunctionInfoArgInfo &info : funcInfo.arguments()) {
36-
if (testIfIsVoidTy(info.type))
37-
info.info = cir::ABIArgInfo::getIgnore();
38-
else
39-
info.info = cir::ABIArgInfo::getDirect(cgt.convertType(info.type));
40-
}
41-
42-
CanQualType retTy = funcInfo.getReturnType();
43-
if (testIfIsVoidTy(retTy))
44-
funcInfo.getReturnInfo() = cir::ABIArgInfo::getIgnore();
45-
else
46-
funcInfo.getReturnInfo() =
47-
cir::ABIArgInfo::getDirect(cgt.convertType(retTy));
48-
}
49-
5029
std::unique_ptr<TargetCIRGenInfo>
5130
clang::CIRGen::createX8664TargetCIRGenInfo(CIRGenTypes &cgt) {
5231
return std::make_unique<X8664TargetCIRGenInfo>(cgt);

0 commit comments

Comments
 (0)