@@ -704,6 +704,14 @@ LowerFunction::buildFunctionEpilog(const LowerFunctionInfo &FI) {
704
704
if (auto al = findAlloca (ret)) {
705
705
rewriter.replaceAllUsesWith (al.getResult (), RVAddr);
706
706
rewriter.eraseOp (al);
707
+ rewriter.setInsertionPoint (ret);
708
+
709
+ auto retInputs = ret.getInput ();
710
+ assert (retInputs.size () == 1 && " return should only have one input" );
711
+ if (auto load = mlir::dyn_cast<LoadOp>(retInputs[0 ].getDefiningOp ()))
712
+ if (load.getResult ().use_empty ())
713
+ rewriter.eraseOp (load);
714
+
707
715
rewriter.replaceOpWithNewOp <ReturnOp>(ret);
708
716
}
709
717
});
@@ -952,6 +960,15 @@ mlir::Value LowerFunction::rewriteCallOp(FuncType calleeTy, FuncOp origCallee,
952
960
return CallResult;
953
961
}
954
962
963
+ mlir::Value createAlloca (mlir::Location loc, mlir::Type type,
964
+ LowerFunction &CGF) {
965
+ auto align = CGF.LM .getDataLayout ().getABITypeAlign (type);
966
+ auto alignAttr = CGF.getRewriter ().getI64IntegerAttr (align.value ());
967
+ return CGF.getRewriter ().create <AllocaOp>(
968
+ loc, CGF.getRewriter ().getType <PointerType>(type), type,
969
+ /* name=*/ llvm::StringRef (" " ), alignAttr);
970
+ }
971
+
955
972
// NOTE(cir): This method has partial parity to CodeGenFunction's EmitCall
956
973
// method in CGCall.cpp. When incrementing it, use the original codegen as a
957
974
// reference: add ABI-specific stuff and skip codegen stuff.
@@ -984,10 +1001,12 @@ mlir::Value LowerFunction::rewriteCallOp(const LowerFunctionInfo &CallInfo,
984
1001
CIRToCIRArgMapping IRFunctionArgs (LM.getContext (), CallInfo);
985
1002
llvm::SmallVector<mlir::Value, 16 > IRCallArgs (IRFunctionArgs.totalIRArgs ());
986
1003
1004
+ mlir::Value sRetPtr ;
987
1005
// If the call returns a temporary with struct return, create a temporary
988
1006
// alloca to hold the result, unless one is given to us.
989
1007
if (RetAI.isIndirect () || RetAI.isCoerceAndExpand () || RetAI.isInAlloca ()) {
990
- cir_cconv_unreachable (" NYI" );
1008
+ sRetPtr = createAlloca (loc, RetTy, *this );
1009
+ IRCallArgs[IRFunctionArgs.getSRetArgNo ()] = sRetPtr ;
991
1010
}
992
1011
993
1012
cir_cconv_assert (!cir::MissingFeatures::swift ());
@@ -1082,6 +1101,32 @@ mlir::Value LowerFunction::rewriteCallOp(const LowerFunctionInfo &CallInfo,
1082
1101
1083
1102
break ;
1084
1103
}
1104
+ case ABIArgInfo::Indirect:
1105
+ case ABIArgInfo::IndirectAliased: {
1106
+ assert (NumIRArgs == 1 );
1107
+ // TODO(cir): For aggregate types
1108
+ // We want to avoid creating an unnecessary temporary+copy here;
1109
+ // however, we need one in three cases:
1110
+ // 1. If the argument is not byval, and we are required to copy the
1111
+ // 2. If the argument is byval, RV is not sufficiently aligned, and
1112
+ // source. (This case doesn't occur on any common architecture.)
1113
+ // we cannot force it to be sufficiently aligned.
1114
+ // 3. If the argument is byval, but RV is not located in default
1115
+ // or alloca address space.
1116
+ cir_cconv_assert (!::cir::MissingFeatures::skipTempCopy ());
1117
+
1118
+ mlir::Value alloca = findAlloca (I->getDefiningOp ());
1119
+
1120
+ // since they are a ARM-specific feature.
1121
+ if (::cir::MissingFeatures::undef ())
1122
+ cir_cconv_unreachable (" NYI" );
1123
+
1124
+ IRCallArgs[FirstIRArg] = alloca ;
1125
+
1126
+ // NOTE(cir): Skipping Emissions, lifetime markers.
1127
+
1128
+ break ;
1129
+ }
1085
1130
default :
1086
1131
llvm::outs () << " Missing ABIArgInfo::Kind: " << ArgInfo.getKind () << " \n " ;
1087
1132
cir_cconv_unreachable (" NYI" );
@@ -1217,6 +1262,10 @@ mlir::Value LowerFunction::rewriteCallOp(const LowerFunctionInfo &CallInfo,
1217
1262
// done in CIRGen
1218
1263
return RetVal;
1219
1264
}
1265
+ case ABIArgInfo::Indirect: {
1266
+ auto load = rewriter.create <LoadOp>(loc, sRetPtr );
1267
+ return load.getResult ();
1268
+ }
1220
1269
default :
1221
1270
llvm::errs () << " Unhandled ABIArgInfo kind: " << RetAI.getKind () << " \n " ;
1222
1271
cir_cconv_unreachable (" NYI" );
0 commit comments