llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits