[clang] [CIR] cir.call with scalar return type (PR #135552)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 13 08:41:19 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Sirui Mu (Lancern)
<details>
<summary>Changes</summary>
This PR introduces support for calling functions with a scalar return type to the upstream. This PR also includes an initial version of `CIRGenTargetInfo` and related definitions which are essential for the CIRGen of call ops.
Related to #<!-- -->132487 .
---
Patch is 32.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135552.diff
21 Files Affected:
- (added) clang/include/clang/CIR/ABIArgInfo.h (+89)
- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+5-3)
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+5-1)
- (modified) clang/include/clang/CIR/MissingFeatures.h (+4)
- (added) clang/lib/CIR/CodeGen/ABIInfo.h (+32)
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+72-10)
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.h (+4)
- (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+19-5)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+2-5)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+11-4)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h (+35-4)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+30)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.h (+6)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+15-4)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.h (+7-2)
- (modified) clang/lib/CIR/CodeGen/CMakeLists.txt (+1)
- (added) clang/lib/CIR/CodeGen/TargetInfo.cpp (+50)
- (added) clang/lib/CIR/CodeGen/TargetInfo.h (+41)
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+28-1)
- (modified) clang/test/CIR/CodeGen/call.cpp (+10)
- (modified) clang/test/CIR/IR/call.cir (+14)
``````````diff
diff --git a/clang/include/clang/CIR/ABIArgInfo.h b/clang/include/clang/CIR/ABIArgInfo.h
new file mode 100644
index 0000000000000..0c2cd85915aa7
--- /dev/null
+++ b/clang/include/clang/CIR/ABIArgInfo.h
@@ -0,0 +1,89 @@
+//==-- ABIArgInfo.h - Abstract info regarding ABI-specific arguments -------==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines ABIArgInfo and associated types used by CIR to track information
+// regarding ABI-coerced types for function arguments and return values. This
+// was moved to the common library as it might be used by both CIRGen and
+// passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CIR_ABIARGINFO_H
+#define LLVM_CLANG_CIR_ABIARGINFO_H
+
+#include "MissingFeatures.h"
+#include "mlir/IR/Types.h"
+
+namespace cir {
+
+class ABIArgInfo {
+public:
+ enum Kind : uint8_t {
+ /// Pass the argument directly using the normal converted CIR type,
+ /// or by coercing to another specified type stored in 'CoerceToType'). If
+ /// an offset is specified (in UIntData), then the argument passed is offset
+ /// by some number of bytes in the memory representation. A dummy argument
+ /// is emitted before the real argument if the specified type stored in
+ /// "PaddingType" is not zero.
+ Direct,
+
+ /// Ignore the argument (treat as void). Useful for void and empty
+ /// structs.
+ Ignore,
+ };
+
+private:
+ mlir::Type typeData;
+ struct DirectAttrInfo {
+ unsigned offset;
+ unsigned align;
+ };
+ union {
+ DirectAttrInfo directAttr;
+ };
+ Kind theKind;
+
+public:
+ ABIArgInfo(Kind k = Direct) : directAttr{0, 0}, theKind(k) {}
+
+ static ABIArgInfo getDirect(mlir::Type ty = nullptr) {
+ ABIArgInfo info(Direct);
+ info.setCoerceToType(ty);
+ return info;
+ }
+
+ static ABIArgInfo getIgnore() { return ABIArgInfo(Ignore); }
+
+ Kind getKind() const { return theKind; }
+ bool isDirect() const { return theKind == Direct; }
+ bool isIgnore() const { return theKind == Ignore; }
+
+ bool canHaveCoerceToType() const {
+ assert(!cir::MissingFeatures::abiArgInfo());
+ return isDirect();
+ }
+
+ unsigned getDirectOffset() const {
+ assert(!cir::MissingFeatures::abiArgInfo());
+ return directAttr.offset;
+ }
+
+ mlir::Type getCoerceToType() const {
+ assert(canHaveCoerceToType() && "invalid kind!");
+ return typeData;
+ }
+
+ void setCoerceToType(mlir::Type ty) {
+ assert(canHaveCoerceToType() && "invalid kind!");
+ typeData = ty;
+ }
+};
+
+} // namespace cir
+
+#endif // LLVM_CLANG_CIR_ABIARGINFO_H
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 68a4505ca7a5a..a24006810c1f5 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,13 +205,15 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
// Call operators
//===--------------------------------------------------------------------===//
- cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee) {
- auto op = create<cir::CallOp>(loc, callee);
+ cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee,
+ mlir::Type returnType = cir::VoidType()) {
+ auto op = create<cir::CallOp>(loc, callee, /*resType=*/returnType);
return op;
}
cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee) {
- return createCallOp(loc, mlir::SymbolRefAttr::get(callee));
+ return createCallOp(loc, mlir::SymbolRefAttr::get(callee),
+ callee.getFunctionType().getReturnType());
}
//===--------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 0d3c2065cd58c..5ba4b33dc1a12 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1408,10 +1408,14 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> {
```
}];
+ let results = (outs Optional<CIR_AnyType>:$result);
let arguments = commonArgs;
- let builders = [OpBuilder<(ins "mlir::SymbolRefAttr":$callee), [{
+ let builders = [OpBuilder<(ins "mlir::SymbolRefAttr":$callee,
+ "mlir::Type":$resType), [{
$_state.addAttribute("callee", callee);
+ if (resType && !isa<VoidType>(resType))
+ $_state.addTypes(resType);
}]>];
}
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index d6a28d4324b32..f692dc661e9d5 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -103,6 +103,8 @@ struct MissingFeatures {
// Misc
static bool cxxABI() { return false; }
+ static bool cirgenABIInfo() { return false; }
+ static bool abiArgInfo() { return false; }
static bool tryEmitAsConstant() { return false; }
static bool constructABIArgDirectExtend() { return false; }
static bool opGlobalViewAttr() { return false; }
@@ -121,6 +123,8 @@ struct MissingFeatures {
static bool fpConstraints() { return false; }
static bool sanitizers() { return false; }
static bool addHeapAllocSiteMetadata() { return false; }
+ static bool targetCIRGenInfoArch() { return false; }
+ static bool targetCIRGenInfoOS() { return false; }
static bool targetCodeGenInfoGetNullPointer() { return false; }
static bool loopInfoStack() { return false; }
static bool requiresCleanups() { return false; }
diff --git a/clang/lib/CIR/CodeGen/ABIInfo.h b/clang/lib/CIR/CodeGen/ABIInfo.h
new file mode 100644
index 0000000000000..157e80f67a67c
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/ABIInfo.h
@@ -0,0 +1,32 @@
+//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CIR_ABIINFO_H
+#define LLVM_CLANG_LIB_CIR_ABIINFO_H
+
+namespace clang::CIRGen {
+
+class CIRGenFunctionInfo;
+class CIRGenTypes;
+
+class ABIInfo {
+ ABIInfo() = delete;
+
+public:
+ CIRGenTypes &cgt;
+
+ ABIInfo(CIRGenTypes &cgt) : cgt(cgt) {}
+
+ virtual ~ABIInfo();
+
+ virtual void computeInfo(CIRGenFunctionInfo &funcInfo) const = 0;
+};
+
+} // namespace clang::CIRGen
+
+#endif // LLVM_CLANG_LIB_CIR_ABIINFO_H
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 1a936458782ea..811750ebfc8b4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -18,9 +18,12 @@
using namespace clang;
using namespace clang::CIRGen;
-CIRGenFunctionInfo *CIRGenFunctionInfo::create() {
- // For now we just create an empty CIRGenFunctionInfo.
- CIRGenFunctionInfo *fi = new CIRGenFunctionInfo();
+CIRGenFunctionInfo *CIRGenFunctionInfo::create(CanQualType resultType) {
+ void *buffer = operator new(totalSizeToAlloc<ArgInfo>(1));
+
+ CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo();
+ fi->getArgsBuffer()[0].type = resultType;
+
return fi;
}
@@ -29,13 +32,29 @@ CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
return *this;
}
-static const CIRGenFunctionInfo &arrangeFreeFunctionLikeCall(CIRGenTypes &cgt) {
+static const CIRGenFunctionInfo &
+arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
+ const FunctionType *fnType) {
+ if (const auto *proto = dyn_cast<FunctionProtoType>(fnType)) {
+ if (proto->isVariadic())
+ cgm.errorNYI("call to variadic function");
+ if (proto->hasExtParameterInfos())
+ cgm.errorNYI("call to functions with extra parameter info");
+ } else if (isa<FunctionNoProtoType>(fnType)) {
+ cgm.errorNYI("call to function without a prototype");
+ }
+
assert(!cir::MissingFeatures::opCallArgs());
- return cgt.arrangeCIRFunctionInfo();
+
+ CanQualType retType = fnType->getReturnType()
+ ->getCanonicalTypeUnqualified()
+ .getUnqualifiedType();
+ return cgt.arrangeCIRFunctionInfo(retType);
}
-const CIRGenFunctionInfo &CIRGenTypes::arrangeFreeFunctionCall() {
- return arrangeFreeFunctionLikeCall(*this);
+const CIRGenFunctionInfo &
+CIRGenTypes::arrangeFreeFunctionCall(const FunctionType *fnType) {
+ return arrangeFreeFunctionLikeCall(*this, cgm, fnType);
}
static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf,
@@ -54,8 +73,12 @@ static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf,
RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
const CIRGenCallee &callee,
+ ReturnValueSlot returnValue,
cir::CIRCallOpInterface *callOp,
mlir::Location loc) {
+ QualType retTy = funcInfo.getReturnType();
+ const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo();
+
assert(!cir::MissingFeatures::opCallArgs());
assert(!cir::MissingFeatures::emitLifetimeMarkers());
@@ -87,9 +110,48 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
assert(!cir::MissingFeatures::opCallMustTail());
assert(!cir::MissingFeatures::opCallReturn());
- // For now we just return nothing because we don't have support for return
- // values yet.
- RValue ret = RValue::get(nullptr);
+ RValue ret;
+ 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]);
+ }
+ default:
+ cgm.errorNYI(loc,
+ "unsupported evaluation kind of function call result");
+ }
+ } else {
+ cgm.errorNYI(loc, "unsupported function call form");
+ }
+
+ break;
+ }
+ 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.
+ ret = getUndefRValue(retTy);
+ break;
+ default:
+ cgm.errorNYI(loc, "unsupported return value information");
+ }
return ret;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.h b/clang/lib/CIR/CodeGen/CIRGenCall.h
index 76fefdca9e45e..4427fda863d7e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.h
@@ -81,6 +81,10 @@ struct CallArg {};
class CallArgList : public llvm::SmallVector<CallArg, 8> {};
+/// Contains the address where the return value of a function can be stored, and
+/// whether the address is volatile or not.
+class ReturnValueSlot {};
+
} // namespace clang::CIRGen
#endif // CLANG_LIB_CODEGEN_CIRGENCALL_H
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index f0732a8ea60af..550231132ab53 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -662,23 +662,36 @@ static CIRGenCallee emitDirectCallee(CIRGenModule &cgm, GlobalDecl gd) {
return CIRGenCallee::forDirect(callee, gd);
}
+RValue CIRGenFunction::getUndefRValue(QualType ty) {
+ if (ty->isVoidType())
+ return RValue::get(nullptr);
+
+ cgm.errorNYI("unsupported type for undef rvalue");
+ return RValue::get(nullptr);
+}
+
RValue CIRGenFunction::emitCall(clang::QualType calleeTy,
const CIRGenCallee &callee,
- const clang::CallExpr *e) {
+ const clang::CallExpr *e,
+ ReturnValueSlot returnValue) {
// Get the actual function type. The callee type will always be a pointer to
// function type or a block pointer type.
assert(calleeTy->isFunctionPointerType() &&
"Callee must have function pointer type!");
calleeTy = getContext().getCanonicalType(calleeTy);
+ auto pointeeTy = cast<PointerType>(calleeTy)->getPointeeType();
if (getLangOpts().CPlusPlus)
assert(!cir::MissingFeatures::sanitizers());
+ const auto *fnType = cast<FunctionType>(pointeeTy);
+
assert(!cir::MissingFeatures::sanitizers());
assert(!cir::MissingFeatures::opCallArgs());
- const CIRGenFunctionInfo &funcInfo = cgm.getTypes().arrangeFreeFunctionCall();
+ const CIRGenFunctionInfo &funcInfo =
+ cgm.getTypes().arrangeFreeFunctionCall(fnType);
assert(!cir::MissingFeatures::opCallNoPrototypeFunc());
assert(!cir::MissingFeatures::opCallChainCall());
@@ -687,7 +700,7 @@ RValue CIRGenFunction::emitCall(clang::QualType calleeTy,
cir::CIRCallOpInterface callOp;
RValue callResult =
- emitCall(funcInfo, callee, &callOp, getLoc(e->getExprLoc()));
+ emitCall(funcInfo, callee, returnValue, &callOp, getLoc(e->getExprLoc()));
assert(!cir::MissingFeatures::generateDebugInfo());
@@ -713,7 +726,8 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
return {};
}
-RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e) {
+RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
+ ReturnValueSlot returnValue) {
assert(!cir::MissingFeatures::objCBlocks());
if (isa<CXXMemberCallExpr>(e)) {
@@ -745,7 +759,7 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e) {
}
assert(!cir::MissingFeatures::opCallPseudoDtor());
- return emitCall(e->getCallee()->getType(), callee, e);
+ return emitCall(e->getCallee()->getType(), callee, e, returnValue);
}
/// Emit code to compute the specified expression, ignoring the result.
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 38104f8533c7d..3dae26dc86f85 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1519,11 +1519,8 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
}
mlir::Value ScalarExprEmitter::VisitCallExpr(const CallExpr *e) {
- if (e->getCallReturnType(cgf.getContext())->isReferenceType()) {
- cgf.getCIRGenModule().errorNYI(
- e->getSourceRange(), "call to function with non-void return type");
- return {};
- }
+ if (e->getCallReturnType(cgf.getContext())->isReferenceType())
+ return emitLoadOfLValue(e);
auto v = cgf.emitCallExpr(e).getScalarVal();
assert(!cir::MissingFeatures::emitLValueAlignmentAssumption());
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index a96d277d0bc0b..01abd84ce1c85 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -269,6 +269,12 @@ class CIRGenFunction : public CIRGenTypeCache {
return LValue::makeAddr(addr, ty, baseInfo);
}
+ /// Get an appropriate 'undef' rvalue for the given type.
+ /// TODO: What's the equivalent for MLIR? Currently we're only using this for
+ /// void types so it just returns RValue::get(nullptr) but it'll need
+ /// addressed later.
+ RValue getUndefRValue(clang::QualType ty);
+
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
cir::FuncType funcType);
@@ -451,11 +457,12 @@ class CIRGenFunction : public CIRGenTypeCache {
mlir::LogicalResult emitBreakStmt(const clang::BreakStmt &s);
RValue emitCall(const CIRGenFunctionInfo &funcInfo,
- const CIRGenCallee &callee, cir::CIRCallOpInterface *callOp,
- mlir::Location loc);
+ const CIRGenCallee &callee, ReturnValueSlot returnValue,
+ cir::CIRCallOpInterface *callOp, mlir::Location loc);
RValue emitCall(clang::QualType calleeTy, const CIRGenCallee &callee,
- const clang::CallExpr *e);
- RValue emitCallExpr(const clang::CallExpr *e);
+ const clang::CallExpr *e, ReturnValueSlot returnValue);
+ RValue emitCallExpr(const clang::CallExpr *e,
+ ReturnValueSlot returnValue = ReturnValueSlot());
CIRGenCallee emitCallee(const clang::Expr *e);
mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
index da73e7a7a9059..c4a2b238c96ae 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
@@ -15,18 +15,49 @@
#ifndef LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H
#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"
namespace clang::CIRGen {
-class CIRGenFunctionInfo final : public llvm::FoldingSetNode {
+struct CIRGenFunctionInfoArgInfo {
+ CanQualType type;
+ cir::ABIArgInfo info;
+};
+
+class CIRGenFunctionInfo final
+ : public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<CIRGenFunctionInfo,
+ CIRGenFunctionInfoArgInfo> {
+ using ArgInfo = CIRGenFunctionInfoArgInfo;
+
+ ArgInfo *getArgsBuffer() { return getTrailingObjects<ArgInfo>(); }
+ const ArgInfo *getArgsBuffer() const { return getTrailingObjects<ArgInfo>(); }
+
public:
- static CIRGenFunctionInfo *create();
+ static CIRGenFunctionInfo *create(CanQualType resultType);
+
+ void operator delete(void *p) { ::operator delete(p); }
+
+ // Friending class TrailingObjects is apparantly not good enough for MSVC, so
+ // these have to be public.
+ friend class TrailingObjects;
// This function has to be CamelCase because llvm::FoldingSet requires so.
// NOLINTNEXTLINE(readability-identifier-naming)
- static void Profile(llvm::FoldingSetNodeID &id) {
- // We don't have anything to profile yet.
+ static void Profile(llvm::FoldingSetNodeID &id, CanQualType resultType) {
+ resultType.Profile(id);
+ }
+
+ void Profile(llvm::FoldingSetNodeID &id) { getReturnType().Profile(id); }
+
+ CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
+
+ cir::ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
+ const cir::ABIArgInfo &getReturnInfo() const {
+ return getArgsBuffer()[0].info;
}
};
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index fd11523ebba61..cbfaa3d89836b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -129,6 +129,36 @@ CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t,
return alignment;
}
+const TargetCIRGenInfo &CIRGenModule::getTargetCIRGenInfo() {
+ if (theTargetCIRGenInfo)
+ return *theTargetCIRGenInfo;
+
+ const llvm::Triple &triple = getTarget().getTriple();
+ switch (triple.getArch()) {
+ default:
+ assert(!cir::MissingFeatures::targetCIRGenInfoArch());
+ errorNYI("unsupported target arch");
+
+ // Currently we just fall through to x86_64.
+ [[fallthrough]];
+
+ case llvm::Triple::x86_64: {
+ switch (triple.getOS()) {
+ default:
+ assert(!cir::MissingFeatures::targetCIRGenInfoOS());
+ errorNYI("unsupported target OS");
+
+ // Currently we just fall through to x86_64.
+ [[fallthrough]];
+
+ case llvm::Triple::...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/135552
More information about the cfe-commits
mailing list