================ @@ -68,20 +168,70 @@ static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf, assert(builder.getInsertionBlock() && "expected valid basic block"); assert(!cir::MissingFeatures::opCallIndirect()); - return builder.createCallOp(callLoc, directFuncOp); + return builder.createCallOp(callLoc, directFuncOp, cirCallArgs); } RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, + const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc) { QualType retTy = funcInfo.getReturnType(); const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo(); - assert(!cir::MissingFeatures::opCallArgs()); + ClangToCIRArgMapping cirFuncArgs(cgm.getASTContext(), funcInfo); + SmallVector<mlir::Value, 16> cirCallArgs(cirFuncArgs.totalCIRArgs()); + 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; + const auto *infoIter = funcInfo.arg_begin(); + for (auto i = args.begin(), e = args.end(); i != e; + ++i, ++infoIter, ++argNo) { + const cir::ABIArgInfo &argInfo = infoIter->info; + + // 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.getKind()) { + case cir::ABIArgInfo::Direct: { + if (!mlir::isa<cir::RecordType>(argInfo.getCoerceToType()) && + argInfo.getCoerceToType() == convertType(infoIter->type) && + argInfo.getDirectOffset() == 0) { + assert(numCIRArgs == 1); + assert(!cir::MissingFeatures::opCallAggregateArgs()); + mlir::Value v = i->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()); ---------------- Lancern wrote:
> I haven't done much work on code that is consuming CIR, but my gut feel is > that it would be best to have an initial state that represents the calls just > as they are, without changing any of the types to meet ABI requirements. I have a feeling that the current CIRGen implementation for function calls is way too complex for a simple and direct mapping from AST to CIR without any ABI considerations. This is due to the fact that we initially followed OG skeleton and thus inherited all the complex handling of function calls from there. Maybe we should start simplifying this piece of CIRGen code after we land a reasonably big enough portion of function call CIRGen code? https://github.com/llvm/llvm-project/pull/136810 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits