@@ -379,10 +379,10 @@ static bool compareFnAttributes(const CodeGenIntrinsic *L,
379
379
return TieL < TieR;
380
380
381
381
// Try to order by readonly/readnone attribute.
382
- uint32_t LK = L->ME .toIntValue ();
383
- uint32_t RK = R->ME .toIntValue ();
384
- if (LK != RK )
385
- return LK > RK ;
382
+ uint32_t LME = L->ME .toIntValue ();
383
+ uint32_t RME = R->ME .toIntValue ();
384
+ if (LME != RME )
385
+ return LME > RME ;
386
386
387
387
return Default;
388
388
}
@@ -404,6 +404,53 @@ struct AttributeComparator {
404
404
};
405
405
} // End anonymous namespace
406
406
407
+ // / Returns the effective MemoryEffects for intrinsic \p Int.
408
+ static MemoryEffects getEffectiveME (const CodeGenIntrinsic &Int) {
409
+ MemoryEffects ME = Int.ME ;
410
+ // TODO: IntrHasSideEffects should affect not only readnone intrinsics.
411
+ if (ME.doesNotAccessMemory () && Int.hasSideEffects )
412
+ ME = MemoryEffects::unknown ();
413
+ return ME;
414
+ }
415
+
416
+ // / Returns true if \p Int has a non-empty set of function attributes. Note that
417
+ // / NoUnwind = !canThrow, so we need to negate it's sense to test if the
418
+ // intrinsic has NoUnwind attribute.
419
+ static bool hasFnAttributes (const CodeGenIntrinsic &Int) {
420
+ return !Int.canThrow || Int.isNoReturn || Int.isNoCallback || Int.isNoSync ||
421
+ Int.isNoFree || Int.isWillReturn || Int.isCold || Int.isNoDuplicate ||
422
+ Int.isNoMerge || Int.isConvergent || Int.isSpeculatable ||
423
+ Int.isStrictFP || getEffectiveME (Int) != MemoryEffects::unknown ();
424
+ }
425
+
426
+ // / Returns the name of the IR enum for argument attribute kind \p Kind.
427
+ static StringRef getArgAttrEnumName (CodeGenIntrinsic::ArgAttrKind Kind) {
428
+ switch (Kind) {
429
+ case CodeGenIntrinsic::NoCapture:
430
+ return " NoCapture" ;
431
+ case CodeGenIntrinsic::NoAlias:
432
+ return " NoAlias" ;
433
+ case CodeGenIntrinsic::NoUndef:
434
+ return " NoUndef" ;
435
+ case CodeGenIntrinsic::NonNull:
436
+ return " NonNull" ;
437
+ case CodeGenIntrinsic::Returned:
438
+ return " Returned" ;
439
+ case CodeGenIntrinsic::ReadOnly:
440
+ return " ReadOnly" ;
441
+ case CodeGenIntrinsic::WriteOnly:
442
+ return " WriteOnly" ;
443
+ case CodeGenIntrinsic::ReadNone:
444
+ return " ReadNone" ;
445
+ case CodeGenIntrinsic::ImmArg:
446
+ return " ImmArg" ;
447
+ case CodeGenIntrinsic::Alignment:
448
+ return " Alignment" ;
449
+ case CodeGenIntrinsic::Dereferenceable:
450
+ return " Dereferenceable" ;
451
+ }
452
+ }
453
+
407
454
// / EmitAttributes - This emits the Intrinsic::getAttributes method.
408
455
void IntrinsicEmitter::EmitAttributes (const CodeGenIntrinsicTable &Ints,
409
456
raw_ostream &OS) {
@@ -425,41 +472,14 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
425
472
continue ;
426
473
427
474
assert (is_sorted (Attrs) && " Argument attributes are not sorted" );
428
- auto getAttrEnumName =
429
- [](CodeGenIntrinsic::ArgAttrKind Kind) -> StringRef {
430
- switch (Kind) {
431
- case CodeGenIntrinsic::NoCapture:
432
- return " NoCapture" ;
433
- case CodeGenIntrinsic::NoAlias:
434
- return " NoAlias" ;
435
- case CodeGenIntrinsic::NoUndef:
436
- return " NoUndef" ;
437
- case CodeGenIntrinsic::NonNull:
438
- return " NonNull" ;
439
- case CodeGenIntrinsic::Returned:
440
- return " Returned" ;
441
- case CodeGenIntrinsic::ReadOnly:
442
- return " ReadOnly" ;
443
- case CodeGenIntrinsic::WriteOnly:
444
- return " WriteOnly" ;
445
- case CodeGenIntrinsic::ReadNone:
446
- return " ReadNone" ;
447
- case CodeGenIntrinsic::ImmArg:
448
- return " ImmArg" ;
449
- case CodeGenIntrinsic::Alignment:
450
- return " Alignment" ;
451
- case CodeGenIntrinsic::Dereferenceable:
452
- return " Dereferenceable" ;
453
- }
454
- };
455
475
456
476
OS << formatv (R"(
457
477
case {0}:
458
478
return AttributeSet::get(C, {{
459
479
)" ,
460
480
ID);
461
481
for (const CodeGenIntrinsic::ArgAttribute &Attr : Attrs) {
462
- StringRef AttrName = getAttrEnumName (Attr.Kind );
482
+ StringRef AttrName = getArgAttrEnumName (Attr.Kind );
463
483
if (Attr.Kind == CodeGenIntrinsic::Alignment ||
464
484
Attr.Kind == CodeGenIntrinsic::Dereferenceable)
465
485
OS << formatv (" Attribute::get(C, Attribute::{0}, {1}),\n " ,
@@ -472,7 +492,8 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
472
492
}
473
493
OS << R"(
474
494
}
475
- } // getIntrinsicArgAttributeSet)" ;
495
+ } // getIntrinsicArgAttributeSet
496
+ )" ;
476
497
477
498
// Compute unique function attribute sets.
478
499
std::map<const CodeGenIntrinsic *, unsigned , FnAttributeComparator>
@@ -481,9 +502,12 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
481
502
static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
482
503
switch (ID) {
483
504
default: llvm_unreachable("Invalid attribute set number");)" ;
484
- for (const CodeGenIntrinsic &Intrinsic : Ints) {
505
+
506
+ for (const CodeGenIntrinsic &Int : Ints) {
507
+ if (!hasFnAttributes (Int))
508
+ continue ;
485
509
unsigned ID = UniqFnAttributes.size ();
486
- if (!UniqFnAttributes.try_emplace (&Intrinsic , ID).second )
510
+ if (!UniqFnAttributes.try_emplace (&Int , ID).second )
487
511
continue ;
488
512
OS << formatv (R"(
489
513
case {0}:
@@ -493,44 +517,42 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
493
517
auto addAttribute = [&OS](StringRef Attr) {
494
518
OS << formatv (" Attribute::get(C, Attribute::{0}),\n " , Attr);
495
519
};
496
- if (!Intrinsic .canThrow )
520
+ if (!Int .canThrow )
497
521
addAttribute (" NoUnwind" );
498
- if (Intrinsic .isNoReturn )
522
+ if (Int .isNoReturn )
499
523
addAttribute (" NoReturn" );
500
- if (Intrinsic .isNoCallback )
524
+ if (Int .isNoCallback )
501
525
addAttribute (" NoCallback" );
502
- if (Intrinsic .isNoSync )
526
+ if (Int .isNoSync )
503
527
addAttribute (" NoSync" );
504
- if (Intrinsic .isNoFree )
528
+ if (Int .isNoFree )
505
529
addAttribute (" NoFree" );
506
- if (Intrinsic .isWillReturn )
530
+ if (Int .isWillReturn )
507
531
addAttribute (" WillReturn" );
508
- if (Intrinsic .isCold )
532
+ if (Int .isCold )
509
533
addAttribute (" Cold" );
510
- if (Intrinsic .isNoDuplicate )
534
+ if (Int .isNoDuplicate )
511
535
addAttribute (" NoDuplicate" );
512
- if (Intrinsic .isNoMerge )
536
+ if (Int .isNoMerge )
513
537
addAttribute (" NoMerge" );
514
- if (Intrinsic .isConvergent )
538
+ if (Int .isConvergent )
515
539
addAttribute (" Convergent" );
516
- if (Intrinsic .isSpeculatable )
540
+ if (Int .isSpeculatable )
517
541
addAttribute (" Speculatable" );
518
- if (Intrinsic .isStrictFP )
542
+ if (Int .isStrictFP )
519
543
addAttribute (" StrictFP" );
520
544
521
- MemoryEffects ME = Intrinsic.ME ;
522
- // TODO: IntrHasSideEffects should affect not only readnone intrinsics.
523
- if (ME.doesNotAccessMemory () && Intrinsic.hasSideEffects )
524
- ME = MemoryEffects::unknown ();
545
+ const MemoryEffects ME = getEffectiveME (Int);
525
546
if (ME != MemoryEffects::unknown ()) {
526
547
OS << formatv (" // {0}\n " , ME);
527
548
OS << formatv (" Attribute::getWithMemoryEffects(C, "
528
549
" MemoryEffects::createFromIntValue({0})),\n " ,
529
550
ME.toIntValue ());
530
551
}
531
- OS << " });\n " ;
552
+ OS << " });" ;
553
+ }
554
+ OS << R"(
532
555
}
533
- OS << R"( }
534
556
} // getIntrinsicFnAttributeSet
535
557
536
558
AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
@@ -585,11 +607,7 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
585
607
NumAttrs++, AttrIdx, ArgAttrID);
586
608
}
587
609
588
- if (!Int.canThrow ||
589
- (Int.ME != MemoryEffects::unknown () && !Int.hasSideEffects ) ||
590
- Int.isNoReturn || Int.isNoCallback || Int.isNoSync || Int.isNoFree ||
591
- Int.isWillReturn || Int.isCold || Int.isNoDuplicate || Int.isNoMerge ||
592
- Int.isConvergent || Int.isSpeculatable || Int.isStrictFP ) {
610
+ if (hasFnAttributes (Int)) {
593
611
unsigned FnAttrID = UniqFnAttributes.find (&Int)->second ;
594
612
OS << formatv (" AS[{0}] = {{AttributeList::FunctionIndex, "
595
613
" getIntrinsicFnAttributeSet(C, {1})};\n " ,
0 commit comments