From 49b79d53675ebcf19ec1b53f1741dbd35705da19 Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Fri, 9 May 2025 12:23:48 -0700 Subject: [PATCH] [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 https://github.com/llvm/clangir/pull/1604 --- clang/lib/CIR/CodeGen/ABIInfo.h | 2 - clang/lib/CIR/CodeGen/CIRGenCall.cpp | 190 +++++---------------- clang/lib/CIR/CodeGen/CIRGenCall.h | 2 + clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h | 7 - clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 22 --- clang/lib/CIR/CodeGen/CIRGenValue.h | 1 + clang/lib/CIR/CodeGen/TargetInfo.cpp | 21 --- 7 files changed, 42 insertions(+), 203 deletions(-) diff --git a/clang/lib/CIR/CodeGen/ABIInfo.h b/clang/lib/CIR/CodeGen/ABIInfo.h index 157e80f67a67..4d03db38cabb 100644 --- a/clang/lib/CIR/CodeGen/ABIInfo.h +++ b/clang/lib/CIR/CodeGen/ABIInfo.h @@ -23,8 +23,6 @@ public: 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 bed0db28818f..149cf1d2018c 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 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 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 cirCallArgs(cirFuncArgs.totalCIRArgs()); + SmallVector 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); + mlir::Type argType = convertType(argInfo.type); + if (!mlir::isa(argType)) { + mlir::Value v; + if (arg.isAggregate()) + cgm.errorNYI(loc, "emitCall: aggregate call argument"); + v = arg.getKnownRValue().getScalarVal(); - switch (argInfo.info.getKind()) { - case cir::ABIArgInfo::Direct: { - if (!mlir::isa(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; - } + // We might have to widen integers, but we should never truncate. + if (argType != v.getType() && mlir::isa(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"); + mlir::Type retCIRTy = convertType(retTy); + if (isa(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"); + // 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"); + 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"); + 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); } - 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. - 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 0e7ab11bfa96..2ba1676eb6b9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.h +++ b/clang/lib/CIR/CodeGen/CIRGenCall.h @@ -102,6 +102,8 @@ public: assert(!hasLV && !isUsed); return rv; } + + bool isAggregate() const { return hasLV || rv.isAggregate(); } }; class CallArgList : public llvm::SmallVector { diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h index 4319f7a2be22..645e6b23c4f7 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 @@ public: 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 89dc5eea7f02..313a6a0edc8e 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 1c453dc9c86b..ce87496aa8c6 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 0b70170cadb6..4a4edb424844 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 @@ public: } // 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 clang::CIRGen::createX8664TargetCIRGenInfo(CIRGenTypes &cgt) { return std::make_unique(cgt);