Skip to content

Commit 79693fa

Browse files
seven-milelanza
authored andcommitted
[CIR][CodeGen][NFCI] Unify attribute list handling of func / call by constructAttributeList (llvm#831)
Similar to llvm#830 , this PR completes the `setCIRFunctionAttributes` part with the call to `constructAttributeList` method, so that func op and call op share the logic of handling these kinds of attributes, which is the design of OG CodeGen. It also includes other refactors. The function `constructAttributeList` now use `mlir::NamedAttrList &` rather than immutable attribute `mlir::DictionaryAttr &` as the inout result parameter, which benefits the additive merging of attributes.
1 parent d3aa1e4 commit 79693fa

File tree

4 files changed

+33
-23
lines changed

4 files changed

+33
-23
lines changed

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -334,16 +334,17 @@ static void AddAttributesFromFunctionProtoType(CIRGenBuilderTy &builder,
334334
/// target-configuration logic, as well as for code defined in library
335335
/// modules such as CUDA's libdevice.
336336
///
337-
/// - ConstructAttributeList builds on top of getDefaultFunctionAttributes
337+
/// - constructAttributeList builds on top of getDefaultFunctionAttributes
338338
/// and adds declaration-specific, convention-specific, and
339339
/// frontend-specific logic. The last is of particular importance:
340340
/// attributes that restrict how the frontend generates code must be
341341
/// added here rather than getDefaultFunctionAttributes.
342342
///
343-
void CIRGenModule::ConstructAttributeList(StringRef Name,
343+
void CIRGenModule::constructAttributeList(StringRef Name,
344344
const CIRGenFunctionInfo &FI,
345345
CIRGenCalleeInfo CalleeInfo,
346-
mlir::DictionaryAttr &Attrs,
346+
mlir::NamedAttrList &funcAttrs,
347+
mlir::cir::CallingConv &callingConv,
347348
bool AttrOnCallSite, bool IsThunk) {
348349
// Implementation Disclaimer
349350
//
@@ -355,13 +356,13 @@ void CIRGenModule::ConstructAttributeList(StringRef Name,
355356
// That said, for the most part, the approach here is very specific compared
356357
// to the rest of CIRGen and attributes and other handling should be done upon
357358
// demand.
358-
mlir::NamedAttrList FuncAttrs;
359359

360360
// Collect function CIR attributes from the CC lowering.
361+
callingConv = FI.getEffectiveCallingConvention();
361362
// TODO: NoReturn, cmse_nonsecure_call
362363

363364
// Collect function CIR attributes from the callee prototype if we have one.
364-
AddAttributesFromFunctionProtoType(getBuilder(), astCtx, FuncAttrs,
365+
AddAttributesFromFunctionProtoType(getBuilder(), astCtx, funcAttrs,
365366
CalleeInfo.getCalleeFunctionProtoType());
366367

367368
const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl();
@@ -378,12 +379,12 @@ void CIRGenModule::ConstructAttributeList(StringRef Name,
378379

379380
if (TargetDecl->hasAttr<NoThrowAttr>()) {
380381
auto nu = mlir::cir::NoThrowAttr::get(builder.getContext());
381-
FuncAttrs.set(nu.getMnemonic(), nu);
382+
funcAttrs.set(nu.getMnemonic(), nu);
382383
}
383384

384385
if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
385386
AddAttributesFromFunctionProtoType(
386-
getBuilder(), astCtx, FuncAttrs,
387+
getBuilder(), astCtx, funcAttrs,
387388
Fn->getType()->getAs<FunctionProtoType>());
388389
if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
389390
// A sane operator new returns a non-aliasing pointer.
@@ -439,8 +440,6 @@ void CIRGenModule::ConstructAttributeList(StringRef Name,
439440
if (TargetDecl->hasAttr<ArmLocallyStreamingAttr>())
440441
;
441442
}
442-
443-
Attrs = mlir::DictionaryAttr::get(builder.getContext(), FuncAttrs);
444443
}
445444

446445
static mlir::cir::CIRCallOpInterface
@@ -679,11 +678,14 @@ RValue CIRGenFunction::buildCall(const CIRGenFunctionInfo &CallInfo,
679678
// TODO: Update the largest vector width if any arguments have vector types.
680679

681680
// Compute the calling convention and attributes.
682-
mlir::DictionaryAttr Attrs;
681+
mlir::NamedAttrList Attrs;
683682
StringRef FnName;
684683
if (auto calleeFnOp = dyn_cast<mlir::cir::FuncOp>(CalleePtr))
685684
FnName = calleeFnOp.getName();
686-
CGM.ConstructAttributeList(FnName, CallInfo, Callee.getAbstractInfo(), Attrs,
685+
686+
mlir::cir::CallingConv callingConv;
687+
CGM.constructAttributeList(FnName, CallInfo, Callee.getAbstractInfo(), Attrs,
688+
callingConv,
687689
/*AttrOnCallSite=*/true,
688690
/*IsThunk=*/false);
689691

@@ -716,7 +718,7 @@ RValue CIRGenFunction::buildCall(const CIRGenFunctionInfo &CallInfo,
716718
} else {
717719
// Otherwise, nounwind call sites will never throw.
718720
auto noThrowAttr = mlir::cir::NoThrowAttr::get(builder.getContext());
719-
CannotThrow = Attrs.contains(noThrowAttr.getMnemonic());
721+
CannotThrow = Attrs.getNamed(noThrowAttr.getMnemonic()).has_value();
720722

721723
if (auto fptr = dyn_cast<mlir::cir::FuncOp>(CalleePtr))
722724
if (fptr.getExtraAttrs().getElements().contains(
@@ -760,10 +762,12 @@ RValue CIRGenFunction::buildCall(const CIRGenFunctionInfo &CallInfo,
760762
indirectFuncVal = CalleePtr->getResult(0);
761763
}
762764

763-
mlir::cir::CIRCallOpInterface callLikeOp = buildCallLikeOp(
764-
*this, callLoc, indirectFuncTy, indirectFuncVal, directFuncOp,
765-
CIRCallArgs, InvokeDest,
766-
mlir::cir::ExtraFuncAttributesAttr::get(builder.getContext(), Attrs));
765+
auto extraFnAttrs = mlir::cir::ExtraFuncAttributesAttr::get(
766+
builder.getContext(), Attrs.getDictionary(builder.getContext()));
767+
768+
mlir::cir::CIRCallOpInterface callLikeOp =
769+
buildCallLikeOp(*this, callLoc, indirectFuncTy, indirectFuncVal,
770+
directFuncOp, CIRCallArgs, InvokeDest, extraFnAttrs);
767771

768772
if (E)
769773
callLikeOp->setAttr(

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,9 +2423,14 @@ void CIRGenModule::setCIRFunctionAttributes(GlobalDecl GD,
24232423
mlir::cir::FuncOp func,
24242424
bool isThunk) {
24252425
// TODO(cir): More logic of constructAttributeList is needed.
2426-
// NOTE(cir): Here we only need CallConv, so a call to constructAttributeList
2427-
// is omitted for simplicity.
2428-
mlir::cir::CallingConv callingConv = info.getEffectiveCallingConvention();
2426+
mlir::cir::CallingConv callingConv;
2427+
2428+
// Initialize PAL with existing attributes to merge attributes.
2429+
mlir::NamedAttrList PAL{func.getExtraAttrs().getElements().getValue()};
2430+
constructAttributeList(func.getName(), info, GD, PAL, callingConv,
2431+
/*AttrOnCallSite=*/false, isThunk);
2432+
func.setExtraAttrsAttr(mlir::cir::ExtraFuncAttributesAttr::get(
2433+
builder.getContext(), PAL.getDictionary(builder.getContext())));
24292434

24302435
// TODO(cir): Check X86_VectorCall incompatibility with WinARM64EC
24312436

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,11 @@ class CIRGenModule : public CIRGenTypeCache {
274274
/// constructed for. If valid, the attributes applied to this decl may
275275
/// contribute to the function attributes and calling convention.
276276
/// \param Attrs [out] - On return, the attribute list to use.
277-
void ConstructAttributeList(StringRef Name, const CIRGenFunctionInfo &Info,
277+
void constructAttributeList(StringRef Name, const CIRGenFunctionInfo &Info,
278278
CIRGenCalleeInfo CalleeInfo,
279-
mlir::DictionaryAttr &Attrs, bool AttrOnCallSite,
280-
bool IsThunk);
279+
mlir::NamedAttrList &Attrs,
280+
mlir::cir::CallingConv &callingConv,
281+
bool AttrOnCallSite, bool IsThunk);
281282

282283
/// Will return a global variable of the given type. If a variable with a
283284
/// different type already exists then a new variable with the right type

clang/test/CIR/CodeGen/delegating-ctor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ DelegatingWithZeroing::DelegatingWithZeroing(int) : DelegatingWithZeroing() {}
3838
// CHECK-NEXT: %2 = cir.load %0 : !cir.ptr<!cir.ptr<!ty_DelegatingWithZeroing>>, !cir.ptr<!ty_DelegatingWithZeroing>
3939
// CHECK-NEXT: %3 = cir.const #cir.zero : !ty_DelegatingWithZeroing
4040
// CHECK-NEXT: cir.store %3, %2 : !ty_DelegatingWithZeroing, !cir.ptr<!ty_DelegatingWithZeroing>
41-
// CHECK-NEXT: cir.call @_ZN21DelegatingWithZeroingC2Ev(%2) : (!cir.ptr<!ty_DelegatingWithZeroing>) -> () extra(#fn_attr1)
41+
// CHECK-NEXT: cir.call @_ZN21DelegatingWithZeroingC2Ev(%2) : (!cir.ptr<!ty_DelegatingWithZeroing>) -> () extra(#fn_attr{{[0-9]*}})
4242
// CHECK-NEXT: cir.return
4343
// CHECK-NEXT: }
4444

0 commit comments

Comments
 (0)