diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index e31024f7dfa8..958947230290 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2866,6 +2866,10 @@ def CIR_OptionalPriorityAttr : OptionalAttr< > >; +// TODO(CIR): CallingConv is a placeholder here so we can use it in +// infrastructure calls, but it currently has no values. +def CIR_CallingConv : CIR_I32EnumAttr<"CallingConv", "calling convention", []>; + def CIR_FuncOp : CIR_Op<"func", [ AutomaticAllocationScope, CallableOpInterface, FunctionOpInterface, DeclareOpInterfaceMethods, diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index c81a26271b4c..210ce63a6b87 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -91,7 +91,6 @@ struct MissingFeatures { static bool opFuncUnwindTablesAttr() { return false; } static bool opFuncWillReturn() { return false; } static bool opFuncNoReturn() { return false; } - static bool setFunctionAttributes() { return false; } static bool setLLVMFunctionFEnvAttributes() { return false; } // CallOp handling diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp index f00cd33a0f27..5fd11c6d97c0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp @@ -110,10 +110,15 @@ static void addAttributesFromFunctionProtoType(CIRGenBuilderTy &builder, } /// Construct the CIR attribute list of a function or call. -void CIRGenModule::constructAttributeList(CIRGenCalleeInfo calleeInfo, - mlir::NamedAttrList &attrs) { +void CIRGenModule::constructAttributeList(llvm::StringRef name, + const CIRGenFunctionInfo &info, + CIRGenCalleeInfo calleeInfo, + mlir::NamedAttrList &attrs, + cir::CallingConv &callingConv, + cir::SideEffect &sideEffect, + bool attrOnCallSite, bool isThunk) { assert(!cir::MissingFeatures::opCallCallConv()); - auto sideEffect = cir::SideEffect::All; + sideEffect = cir::SideEffect::All; addAttributesFromFunctionProtoType(getBuilder(), attrs, calleeInfo.getCalleeFunctionProtoType()); @@ -631,7 +636,11 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo, assert(!cir::MissingFeatures::opCallCallConv()); assert(!cir::MissingFeatures::opCallAttrs()); - cgm.constructAttributeList(callee.getAbstractInfo(), attrs); + cir::CallingConv callingConv; + cir::SideEffect sideEffect; + cgm.constructAttributeList(funcName, funcInfo, callee.getAbstractInfo(), + attrs, callingConv, sideEffect, + /*attrOnCallSite=*/true, /*isThunk=*/false); cir::FuncType indirectFuncTy; mlir::Value indirectFuncVal; diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 44fe9cbd9687..61d84f197e6e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -2130,6 +2130,34 @@ void CIRGenModule::setTLSMode(mlir::Operation *op, const VarDecl &d) { global.setTlsModel(tlm); } +void CIRGenModule::setCIRFunctionAttributes(GlobalDecl globalDecl, + const CIRGenFunctionInfo &info, + cir::FuncOp func, bool isThunk) { + // TODO(cir): More logic of constructAttributeList is needed. + cir::CallingConv callingConv; + cir::SideEffect sideEffect; + + // TODO(cir): The current list should be initialized with the extra function + // attributes, but we don't have those yet. For now, the PAL is initialized + // with nothing. + assert(!cir::MissingFeatures::opFuncExtraAttrs()); + // Initialize PAL with existing attributes to merge attributes. + mlir::NamedAttrList pal{}; + constructAttributeList(func.getName(), info, globalDecl, pal, callingConv, + sideEffect, + /*attrOnCallSite=*/false, isThunk); + // TODO(cir): we need to set Extra Attrs here when that gets implemented. + assert(!cir::MissingFeatures::opFuncExtraAttrs()); + + // TODO(cir): Check X86_VectorCall incompatibility wiht WinARM64EC + + // TODO(cir): typically the calling conv is set right here, but since + // cir::CallingConv is empty and we've not yet added calling-conv to FuncOop, + // this isn't really useful here. This should call func.setCallingConv/etc + // later. + assert(!cir::MissingFeatures::opFuncCallingConv()); +} + void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl, cir::FuncOp func, bool isIncompleteFunction, @@ -2138,7 +2166,11 @@ void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl, // represent them in dedicated ops. The correct attributes are ensured during // translation to LLVM. Thus, we don't need to check for them here. - assert(!cir::MissingFeatures::setFunctionAttributes()); + if (!isIncompleteFunction) + setCIRFunctionAttributes(globalDecl, + getTypes().arrangeGlobalDeclaration(globalDecl), + func, isThunk); + assert(!cir::MissingFeatures::setTargetAttributes()); // TODO(cir): This needs a lot of work to better match CodeGen. That diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index db63a5d63637..a897020ffcd5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -255,11 +255,24 @@ public: /// Get the CIR attributes and calling convention to use for a particular /// function type. /// + /// \param name - The function name. + /// \param info - The function type information. /// \param calleeInfo - The callee information these attributes are being /// constructed for. If valid, the attributes applied to this decl may /// contribute to the function attributes and calling convention. - void constructAttributeList(CIRGenCalleeInfo calleeInfo, - mlir::NamedAttrList &attrs); + /// \param attrs [out] - On return, the attribute list to use. + /// \param callingConv [out] - On return, the calling convention to use. + /// \param sideEffect [out] - On return, the side effect type of the + /// attributes. + /// \param attrOnCallSite - Whether or not the attributes are on a call site. + /// \param isThunk - Whether the function is a thunk. + void constructAttributeList(llvm::StringRef name, + const CIRGenFunctionInfo &info, + CIRGenCalleeInfo calleeInfo, + mlir::NamedAttrList &attrs, + cir::CallingConv &callingConv, + cir::SideEffect &sideEffect, bool attrOnCallSite, + bool isThunk); /// Will return a global variable of the given type. If a variable with a /// different type already exists then a new variable with the right type @@ -458,6 +471,10 @@ public: void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, bool isIncompleteFunction, bool isThunk); + /// Set the CIR function attributes (Sext, zext, etc). + void setCIRFunctionAttributes(GlobalDecl gd, const CIRGenFunctionInfo &info, + cir::FuncOp func, bool isThunk); + /// Set extra attributes (inline, etc.) for a function. void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f);