@@ -2506,84 +2506,168 @@ void CIRGenModule::setCIRFunctionAttributesForDefinition(const Decl *decl,
2506
2506
attrs.set (attr.getMnemonic (), attr);
2507
2507
}
2508
2508
2509
+ if (codeGenOpts.StackClashProtector )
2510
+ llvm_unreachable (" NYI" );
2511
+
2512
+ if (codeGenOpts.StackProbeSize && codeGenOpts.StackProbeSize != 4096 )
2513
+ llvm_unreachable (" NYI" );
2514
+
2509
2515
if (!hasUnwindExceptions (getLangOpts ())) {
2510
2516
auto attr = cir::NoThrowAttr::get (&getMLIRContext ());
2511
2517
attrs.set (attr.getMnemonic (), attr);
2512
2518
}
2513
2519
2520
+ assert (!MissingFeatures::stackProtector ());
2521
+
2522
+ auto existingInlineAttr = dyn_cast_if_present<cir::InlineAttr>(
2523
+ attrs.get (cir::InlineAttr::getMnemonic ()));
2524
+ bool isNoInline = existingInlineAttr && existingInlineAttr.isNoInline ();
2525
+ bool isAlwaysInline =
2526
+ existingInlineAttr && existingInlineAttr.isAlwaysInline ();
2527
+
2514
2528
if (!decl) {
2515
- // If we don't have a declaration to control inlining, the function isn't
2516
- // explicitly marked as alwaysinline for semantic reasons, and inlining is
2517
- // disabled, mark the function as noinline.
2518
- if (codeGenOpts.getInlining () == CodeGenOptions::OnlyAlwaysInlining) {
2529
+ // Non-entry HLSL functions must always be inlined.
2530
+ if (getLangOpts ().HLSL && !isNoInline) {
2519
2531
auto attr = cir::InlineAttr::get (&getMLIRContext (),
2520
2532
cir::InlineKind::AlwaysInline);
2521
2533
attrs.set (attr.getMnemonic (), attr);
2534
+ } else if (!isAlwaysInline && codeGenOpts.getInlining () ==
2535
+ CodeGenOptions::OnlyAlwaysInlining) {
2536
+ // If we don't have a declaration to control inlining, the function isn't
2537
+ // explicitly marked as alwaysinline for semantic reasons, and inlining is
2538
+ // disabled, mark the function as noinline.
2539
+ auto attr =
2540
+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline);
2541
+ attrs.set (attr.getMnemonic (), attr);
2522
2542
}
2523
- } else if (decl->hasAttr <NoInlineAttr>()) {
2543
+
2544
+ f.setExtraAttrsAttr (cir::ExtraFuncAttributesAttr::get (
2545
+ &getMLIRContext (), attrs.getDictionary (&getMLIRContext ())));
2546
+ return ;
2547
+ }
2548
+
2549
+ // Handle SME attributes that apply to function definitions,
2550
+ // rather than to function prototypes.
2551
+ if (decl->hasAttr <ArmLocallyStreamingAttr>())
2552
+ llvm_unreachable (" NYI" );
2553
+
2554
+ if (auto *attr = decl->getAttr <ArmNewAttr>()) {
2555
+ if (attr->isNewZA ())
2556
+ llvm_unreachable (" NYI" );
2557
+ if (attr->isNewZT0 ())
2558
+ llvm_unreachable (" NYI" );
2559
+ }
2560
+
2561
+ // Track whether we need to add the optnone attribute,
2562
+ // starting with the default for this optimization level.
2563
+ bool shouldAddOptNone =
2564
+ !codeGenOpts.DisableO0ImplyOptNone && codeGenOpts.OptimizationLevel == 0 ;
2565
+ // We can't add optnone in the following cases, it won't pass the verifier.
2566
+ shouldAddOptNone &= !decl->hasAttr <MinSizeAttr>();
2567
+ shouldAddOptNone &= !decl->hasAttr <AlwaysInlineAttr>();
2568
+
2569
+ // Non-entry HLSL functions must always be inlined.
2570
+ if (getLangOpts ().HLSL && !isNoInline && !decl->hasAttr <NoInlineAttr>()) {
2571
+ auto attr =
2572
+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::AlwaysInline);
2573
+ attrs.set (attr.getMnemonic (), attr);
2574
+ } else if ((shouldAddOptNone || decl->hasAttr <OptimizeNoneAttr>()) &&
2575
+ !isAlwaysInline) {
2576
+ // Add optnone, but do so only if the function isn't always_inline.
2577
+ auto optNoneAttr = cir::OptNoneAttr::get (&getMLIRContext ());
2578
+ attrs.set (optNoneAttr.getMnemonic (), optNoneAttr);
2579
+
2580
+ // OptimizeNone implies noinline; we should not be inlining such functions.
2581
+ auto noInlineAttr =
2582
+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline);
2583
+ attrs.set (noInlineAttr.getMnemonic (), noInlineAttr);
2584
+
2585
+ // We still need to handle naked functions even though optnone subsumes
2586
+ // much of their semantics.
2587
+ if (decl->hasAttr <NakedAttr>())
2588
+ llvm_unreachable (" NYI" );
2589
+
2590
+ // OptimizeNone wins over OptimizeForSize and MinSize.
2591
+ assert (!MissingFeatures::optimizeForSize ());
2592
+ assert (!MissingFeatures::minSize ());
2593
+ } else if (decl->hasAttr <NakedAttr>()) {
2594
+ // Naked implies noinline: we should not be inlining such functions.
2595
+ llvm_unreachable (" NYI" );
2596
+ } else if (decl->hasAttr <NoDuplicateAttr>()) {
2597
+ llvm_unreachable (" NYI" );
2598
+ } else if (decl->hasAttr <NoInlineAttr>() && !isAlwaysInline) {
2524
2599
// Add noinline if the function isn't always_inline.
2525
2600
auto attr =
2526
2601
cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline);
2527
2602
attrs.set (attr.getMnemonic (), attr);
2528
- } else if (decl->hasAttr <AlwaysInlineAttr>()) {
2603
+ } else if (decl->hasAttr <AlwaysInlineAttr>() && !isNoInline ) {
2529
2604
// (noinline wins over always_inline, and we can't specify both in IR)
2530
2605
auto attr =
2531
2606
cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::AlwaysInline);
2532
2607
attrs.set (attr.getMnemonic (), attr);
2533
2608
} else if (codeGenOpts.getInlining () == CodeGenOptions::OnlyAlwaysInlining) {
2534
2609
// If we're not inlining, then force everything that isn't always_inline
2535
2610
// to carry an explicit noinline attribute.
2536
- auto attr =
2537
- cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline);
2538
- attrs.set (attr.getMnemonic (), attr);
2611
+ if (!isAlwaysInline) {
2612
+ auto attr =
2613
+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline);
2614
+ attrs.set (attr.getMnemonic (), attr);
2615
+ }
2539
2616
} else {
2540
2617
// Otherwise, propagate the inline hint attribute and potentially use its
2541
2618
// absence to mark things as noinline.
2542
2619
// Search function and template pattern redeclarations for inline.
2543
- auto CheckForInline = [](const FunctionDecl *decl) {
2544
- auto CheckRedeclForInline = [](const FunctionDecl *Redecl) {
2545
- return Redecl->isInlineSpecified ();
2620
+ if (auto *fd = dyn_cast<FunctionDecl>(decl)) {
2621
+ auto checkForInline = [](const FunctionDecl *decl) {
2622
+ auto checkRedeclForInline = [](const FunctionDecl *redecl) {
2623
+ return redecl->isInlineSpecified ();
2624
+ };
2625
+ if (any_of (decl->redecls (), checkRedeclForInline))
2626
+ return true ;
2627
+ const FunctionDecl *pattern = decl->getTemplateInstantiationPattern ();
2628
+ if (!pattern)
2629
+ return false ;
2630
+ return any_of (pattern->redecls (), checkRedeclForInline);
2546
2631
};
2547
- if (any_of (decl->redecls (), CheckRedeclForInline))
2548
- return true ;
2549
- const FunctionDecl *Pattern = decl->getTemplateInstantiationPattern ();
2550
- if (!Pattern)
2551
- return false ;
2552
- return any_of (Pattern->redecls (), CheckRedeclForInline);
2553
- };
2554
- if (CheckForInline (cast<FunctionDecl>(decl))) {
2555
- auto attr =
2556
- cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::InlineHint);
2557
- attrs.set (attr.getMnemonic (), attr);
2558
- } else if (codeGenOpts.getInlining () == CodeGenOptions::OnlyHintInlining) {
2559
- auto attr =
2560
- cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline);
2561
- attrs.set (attr.getMnemonic (), attr);
2632
+ if (checkForInline (fd)) {
2633
+ auto attr = cir::InlineAttr::get (&getMLIRContext (),
2634
+ cir::InlineKind::InlineHint);
2635
+ attrs.set (attr.getMnemonic (), attr);
2636
+ } else if (codeGenOpts.getInlining () ==
2637
+ CodeGenOptions::OnlyHintInlining &&
2638
+ !fd->isInlined () && !isAlwaysInline) {
2639
+ auto attr =
2640
+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline);
2641
+ attrs.set (attr.getMnemonic (), attr);
2642
+ }
2562
2643
}
2563
2644
}
2564
2645
2565
- // Track whether we need to add the optnone attribute,
2566
- // starting with the default for this optimization level.
2567
- bool ShouldAddOptNone =
2568
- !codeGenOpts.DisableO0ImplyOptNone && codeGenOpts.OptimizationLevel == 0 ;
2569
- if (decl) {
2570
- ShouldAddOptNone &= !decl->hasAttr <MinSizeAttr>();
2571
- ShouldAddOptNone &= !decl->hasAttr <AlwaysInlineAttr>();
2572
- ShouldAddOptNone |= decl->hasAttr <OptimizeNoneAttr>();
2646
+ // Add other optimization related attributes if we are optimizing this
2647
+ // function.
2648
+ if (!decl->hasAttr <OptimizeNoneAttr>()) {
2649
+ if (decl->hasAttr <ColdAttr>()) {
2650
+ llvm_unreachable (" NYI" );
2651
+ }
2652
+ if (decl->hasAttr <HotAttr>())
2653
+ llvm_unreachable (" NYI" );
2654
+ if (decl->hasAttr <MinSizeAttr>())
2655
+ assert (!MissingFeatures::minSize ());
2573
2656
}
2574
2657
2575
- if (ShouldAddOptNone) {
2576
- auto optNoneAttr = cir::OptNoneAttr::get (&getMLIRContext ());
2577
- attrs.set (optNoneAttr.getMnemonic (), optNoneAttr);
2658
+ f.setExtraAttrsAttr (cir::ExtraFuncAttributesAttr::get (
2659
+ &getMLIRContext (), attrs.getDictionary (&getMLIRContext ())));
2578
2660
2579
- // OptimizeNone implies noinline; we should not be inlining such functions.
2580
- auto noInlineAttr =
2581
- cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline);
2582
- attrs.set (noInlineAttr.getMnemonic (), noInlineAttr);
2661
+ assert (!MissingFeatures::setFunctionAlignment ());
2662
+
2663
+ // In the cross-dso CFI mode with canonical jump tables, we want !type
2664
+ // attributes on definitions only.
2665
+ if (codeGenOpts.SanitizeCfiCrossDso &&
2666
+ codeGenOpts.SanitizeCfiCanonicalJumpTables ) {
2667
+ llvm_unreachable (" NYI" );
2583
2668
}
2584
2669
2585
- f.setExtraAttrsAttr (cir::ExtraFuncAttributesAttr::get (
2586
- &getMLIRContext (), attrs.getDictionary (&getMLIRContext ())));
2670
+ assert (!MissingFeatures::memberFunctionPointerTypeMetadata ());
2587
2671
}
2588
2672
2589
2673
void CIRGenModule::setCIRFunctionAttributes (GlobalDecl GD,
0 commit comments