[clang] [CIR][NFC] Remove ABI handling from CIRGen call handling (PR #139159)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 8 14:19:27 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Andy Kaylor (andykaylor)
<details>
<summary>Changes</summary>
This corresponds to the changes made in https://github.com/llvm/clangir/pull/1604
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/139159.diff
7 Files Affected:
- (modified) clang/lib/CIR/CodeGen/ABIInfo.h (-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+42-154)
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.h (+2)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h (-7)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (-22)
- (modified) clang/lib/CIR/CodeGen/CIRGenValue.h (+1)
- (modified) clang/lib/CIR/CodeGen/TargetInfo.cpp (-21)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/ABIInfo.h b/clang/lib/CIR/CodeGen/ABIInfo.h
index 157e80f67a67c..4d03db38cabb9 100644
--- a/clang/lib/CIR/CodeGen/ABIInfo.h
+++ b/clang/lib/CIR/CodeGen/ABIInfo.h
@@ -23,8 +23,6 @@ class ABIInfo {
ABIInfo(CIRGenTypes &cgt) : cgt(cgt) {}
virtual ~ABIInfo();
-
- virtual void computeInfo(CIRGenFunctionInfo &funcInfo) const = 0;
};
} // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index bed0db28818f1..149cf1d2018c5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -39,86 +39,6 @@ CIRGenFunctionInfo::create(CanQualType resultType,
return fi;
}
-namespace {
-
-/// Encapsulates information about the way function arguments from
-/// CIRGenFunctionInfo should be passed to actual CIR function.
-class ClangToCIRArgMapping {
- static constexpr unsigned invalidIndex = ~0U;
- unsigned totalNumCIRArgs;
-
- /// Arguments of CIR function corresponding to single Clang argument.
- struct CIRArgs {
- // Argument is expanded to CIR arguments at positions
- // [FirstArgIndex, FirstArgIndex + NumberOfArgs).
- unsigned firstArgIndex = 0;
- unsigned numberOfArgs = 0;
-
- CIRArgs() : firstArgIndex(invalidIndex), numberOfArgs(0) {}
- };
-
- SmallVector<CIRArgs, 8> argInfo;
-
-public:
- ClangToCIRArgMapping(const ASTContext &astContext,
- const CIRGenFunctionInfo &funcInfo)
- : totalNumCIRArgs(0), argInfo(funcInfo.arg_size()) {
- unsigned cirArgNo = 0;
-
- assert(!cir::MissingFeatures::opCallABIIndirectArg());
-
- unsigned argNo = 0;
- for (const CIRGenFunctionInfoArgInfo &i : funcInfo.arguments()) {
- // Collect data about CIR arguments corresponding to Clang argument ArgNo.
- CIRArgs &cirArgs = argInfo[argNo];
-
- assert(!cir::MissingFeatures::opCallPaddingArgs());
-
- switch (i.info.getKind()) {
- default:
- assert(!cir::MissingFeatures::abiArgInfo());
- // For now we just fall through. More argument kinds will be added later
- // as the upstreaming proceeds.
- [[fallthrough]];
- case cir::ABIArgInfo::Direct:
- // Postpone splitting structs into elements since this makes it way
- // more complicated for analysis to obtain information on the original
- // arguments.
- //
- // TODO(cir): a LLVM lowering prepare pass should break this down into
- // the appropriated pieces.
- assert(!cir::MissingFeatures::opCallABIExtendArg());
- cirArgs.numberOfArgs = 1;
- break;
- }
-
- if (cirArgs.numberOfArgs > 0) {
- cirArgs.firstArgIndex = cirArgNo;
- cirArgNo += cirArgs.numberOfArgs;
- }
-
- ++argNo;
- }
-
- assert(argNo == argInfo.size());
- assert(!cir::MissingFeatures::opCallInAlloca());
-
- totalNumCIRArgs = cirArgNo;
- }
-
- unsigned totalCIRArgs() const { return totalNumCIRArgs; }
-
- /// Returns index of first CIR argument corresponding to argNo, and their
- /// quantity.
- std::pair<unsigned, unsigned> getCIRArgs(unsigned argNo) const {
- assert(argNo < argInfo.size());
- return std::make_pair(argInfo[argNo].firstArgIndex,
- argInfo[argNo].numberOfArgs);
- }
-};
-
-} // namespace
-
CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
assert(!cir::MissingFeatures::opCallVirtual());
return *this;
@@ -175,56 +95,38 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
cir::CIRCallOpInterface *callOp,
mlir::Location loc) {
QualType retTy = funcInfo.getReturnType();
- const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo();
- ClangToCIRArgMapping cirFuncArgs(cgm.getASTContext(), funcInfo);
- SmallVector<mlir::Value, 16> cirCallArgs(cirFuncArgs.totalCIRArgs());
+ SmallVector<mlir::Value, 16> cirCallArgs(args.size());
assert(!cir::MissingFeatures::emitLifetimeMarkers());
// Translate all of the arguments as necessary to match the CIR lowering.
- assert(funcInfo.arg_size() == args.size() &&
- "Mismatch between function signature & arguments.");
- unsigned argNo = 0;
- for (const auto &[arg, argInfo] : llvm::zip(args, funcInfo.arguments())) {
+ for (auto [argNo, arg, argInfo] :
+ llvm::enumerate(args, funcInfo.arguments())) {
// Insert a padding argument to ensure proper alignment.
assert(!cir::MissingFeatures::opCallPaddingArgs());
- unsigned firstCIRArg;
- unsigned numCIRArgs;
- std::tie(firstCIRArg, numCIRArgs) = cirFuncArgs.getCIRArgs(argNo);
-
- switch (argInfo.info.getKind()) {
- case cir::ABIArgInfo::Direct: {
- if (!mlir::isa<cir::RecordType>(argInfo.info.getCoerceToType()) &&
- argInfo.info.getCoerceToType() == convertType(argInfo.type) &&
- argInfo.info.getDirectOffset() == 0) {
- assert(numCIRArgs == 1);
- assert(!cir::MissingFeatures::opCallAggregateArgs());
- mlir::Value v = arg.getKnownRValue().getScalarVal();
-
- assert(!cir::MissingFeatures::opCallExtParameterInfo());
-
- // We might have to widen integers, but we should never truncate.
- assert(!cir::MissingFeatures::opCallWidenArg());
-
- // If the argument doesn't match, perform a bitcast to coerce it. This
- // can happen due to trivial type mismatches.
- assert(!cir::MissingFeatures::opCallBitcastArg());
-
- cirCallArgs[firstCIRArg] = v;
- break;
- }
-
+ mlir::Type argType = convertType(argInfo.type);
+ if (!mlir::isa<cir::RecordType>(argType)) {
+ mlir::Value v;
+ if (arg.isAggregate())
+ cgm.errorNYI(loc, "emitCall: aggregate call argument");
+ v = arg.getKnownRValue().getScalarVal();
+
+ // We might have to widen integers, but we should never truncate.
+ if (argType != v.getType() && mlir::isa<cir::IntType>(v.getType()))
+ cgm.errorNYI(loc, "emitCall: widening integer call argument");
+
+ // If the argument doesn't match, perform a bitcast to coerce it. This
+ // can happen due to trivial type mismatches.
+ // TODO(cir): When getFunctionType is added, assert that this isn't
+ // needed.
+ assert(!cir::MissingFeatures::opCallBitcastArg());
+ cirCallArgs[argNo] = v;
+ } else {
assert(!cir::MissingFeatures::opCallAggregateArgs());
cgm.errorNYI("emitCall: aggregate function call argument");
- break;
- }
- default:
- cgm.errorNYI("unsupported argument kind");
}
-
- ++argNo;
}
const CIRGenCallee &concreteCallee = callee.prepareConcreteCallee(*this);
@@ -256,45 +158,31 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
assert(!cir::MissingFeatures::opCallMustTail());
assert(!cir::MissingFeatures::opCallReturn());
- switch (retInfo.getKind()) {
- case cir::ABIArgInfo::Direct: {
- mlir::Type retCIRTy = convertType(retTy);
- if (retInfo.getCoerceToType() == retCIRTy &&
- retInfo.getDirectOffset() == 0) {
- switch (getEvaluationKind(retTy)) {
- case cir::TEK_Scalar: {
- mlir::ResultRange results = theCall->getOpResults();
- assert(results.size() == 1 && "unexpected number of returns");
-
- // If the argument doesn't match, perform a bitcast to coerce it. This
- // can happen due to trivial type mismatches.
- if (results[0].getType() != retCIRTy)
- cgm.errorNYI(loc, "bitcast on function return value");
-
- mlir::Region *region = builder.getBlock()->getParent();
- if (region != theCall->getParentRegion())
- cgm.errorNYI(loc, "function calls with cleanup");
-
- return RValue::get(results[0]);
- }
- case cir::TEK_Complex:
- case cir::TEK_Aggregate:
- cgm.errorNYI(loc,
- "unsupported evaluation kind of function call result");
- return getUndefRValue(retTy);
- }
- llvm_unreachable("Invalid evaluation kind");
- }
- cgm.errorNYI(loc, "unsupported function call form");
+ mlir::Type retCIRTy = convertType(retTy);
+ if (isa<cir::VoidType>(retCIRTy))
return getUndefRValue(retTy);
+ switch (getEvaluationKind(retTy)) {
+ case cir::TEK_Scalar: {
+ mlir::ResultRange results = theCall->getOpResults();
+ assert(results.size() == 1 && "unexpected number of returns");
+
+ // If the argument doesn't match, perform a bitcast to coerce it. This
+ // can happen due to trivial type mismatches.
+ if (results[0].getType() != retCIRTy)
+ cgm.errorNYI(loc, "bitcast on function return value");
+
+ mlir::Region *region = builder.getBlock()->getParent();
+ if (region != theCall->getParentRegion())
+ cgm.errorNYI(loc, "function calls with cleanup");
+
+ return RValue::get(results[0]);
}
- case cir::ABIArgInfo::Ignore:
- // If we are ignoring an argument that had a result, make sure to construct
- // the appropriate return value for our caller.
+ case cir::TEK_Complex:
+ case cir::TEK_Aggregate:
+ cgm.errorNYI(loc, "unsupported evaluation kind of function call result");
return getUndefRValue(retTy);
}
-
- llvm_unreachable("Invalid return info kind");
+ llvm_unreachable("Invalid evaluation kind");
}
void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.h b/clang/lib/CIR/CodeGen/CIRGenCall.h
index 0e7ab11bfa96c..2ba1676eb6b97 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.h
@@ -102,6 +102,8 @@ struct CallArg {
assert(!hasLV && !isUsed);
return rv;
}
+
+ bool isAggregate() const { return hasLV || rv.isAggregate(); }
};
class CallArgList : public llvm::SmallVector<CallArg, 8> {
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
index 4319f7a2be225..645e6b23c4f76 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
@@ -16,7 +16,6 @@
#define LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H
#include "clang/AST/CanonicalType.h"
-#include "clang/CIR/ABIArgInfo.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/TrailingObjects.h"
@@ -24,7 +23,6 @@ namespace clang::CIRGen {
struct CIRGenFunctionInfoArgInfo {
CanQualType type;
- cir::ABIArgInfo info;
};
class CIRGenFunctionInfo final
@@ -77,11 +75,6 @@ class CIRGenFunctionInfo final
unsigned arg_size() const { return numArgs; }
CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
-
- cir::ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
- const cir::ABIArgInfo &getReturnInfo() const {
- return getArgsBuffer()[0].info;
- }
};
} // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 89dc5eea7f028..313a6a0edc8ef 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -538,27 +538,5 @@ const CIRGenFunctionInfo &CIRGenTypes::arrangeCIRFunctionInfo(
fi = CIRGenFunctionInfo::create(returnType, argTypes);
functionInfos.InsertNode(fi, insertPos);
- bool inserted = functionsBeingProcessed.insert(fi).second;
- (void)inserted;
- assert(inserted && "Are functions being processed recursively?");
-
- assert(!cir::MissingFeatures::opCallCallConv());
- getABIInfo().computeInfo(*fi);
-
- // Loop over all of the computed argument and return value info. If any of
- // them are direct or extend without a specified coerce type, specify the
- // default now.
- cir::ABIArgInfo &retInfo = fi->getReturnInfo();
- if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr)
- retInfo.setCoerceToType(convertType(fi->getReturnType()));
-
- for (CIRGenFunctionInfoArgInfo &i : fi->arguments())
- if (i.info.canHaveCoerceToType() && i.info.getCoerceToType() == nullptr)
- i.info.setCoerceToType(convertType(i.type));
-
- bool erased = functionsBeingProcessed.erase(fi);
- (void)erased;
- assert(erased && "Not in set?");
-
return *fi;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h
index 1c453dc9c86b5..ce87496aa8c64 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -43,6 +43,7 @@ class RValue {
public:
bool isScalar() const { return v1.getInt() == Scalar; }
+ bool isAggregate() const { return v1.getInt() == Aggregate; }
/// Return the mlir::Value of this scalar value.
mlir::Value getScalarVal() const {
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp
index 0b70170cadb69..4a4edb4248447 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp
@@ -16,8 +16,6 @@ namespace {
class X8664ABIInfo : public ABIInfo {
public:
X8664ABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
-
- void computeInfo(CIRGenFunctionInfo &funcInfo) const override;
};
class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
@@ -28,25 +26,6 @@ class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
} // namespace
-void X8664ABIInfo::computeInfo(CIRGenFunctionInfo &funcInfo) const {
- // Top level CIR has unlimited arguments and return types. Lowering for ABI
- // specific concerns should happen during a lowering phase. Assume everything
- // is direct for now.
- for (CIRGenFunctionInfoArgInfo &info : funcInfo.arguments()) {
- if (testIfIsVoidTy(info.type))
- info.info = cir::ABIArgInfo::getIgnore();
- else
- info.info = cir::ABIArgInfo::getDirect(cgt.convertType(info.type));
- }
-
- CanQualType retTy = funcInfo.getReturnType();
- if (testIfIsVoidTy(retTy))
- funcInfo.getReturnInfo() = cir::ABIArgInfo::getIgnore();
- else
- funcInfo.getReturnInfo() =
- cir::ABIArgInfo::getDirect(cgt.convertType(retTy));
-}
-
std::unique_ptr<TargetCIRGenInfo>
clang::CIRGen::createX8664TargetCIRGenInfo(CIRGenTypes &cgt) {
return std::make_unique<X8664TargetCIRGenInfo>(cgt);
``````````
</details>
https://github.com/llvm/llvm-project/pull/139159
More information about the cfe-commits
mailing list