@@ -379,10 +379,10 @@ static bool compareFnAttributes(const CodeGenIntrinsic *L,
379379 return TieL < TieR;
380380
381381 // 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 ;
386386
387387 return Default;
388388}
@@ -404,6 +404,53 @@ struct AttributeComparator {
404404};
405405} // End anonymous namespace
406406
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+
407454// / EmitAttributes - This emits the Intrinsic::getAttributes method.
408455void IntrinsicEmitter::EmitAttributes (const CodeGenIntrinsicTable &Ints,
409456 raw_ostream &OS) {
@@ -425,41 +472,14 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
425472 continue ;
426473
427474 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- };
455475
456476 OS << formatv (R"(
457477 case {0}:
458478 return AttributeSet::get(C, {{
459479)" ,
460480 ID);
461481 for (const CodeGenIntrinsic::ArgAttribute &Attr : Attrs) {
462- StringRef AttrName = getAttrEnumName (Attr.Kind );
482+ StringRef AttrName = getArgAttrEnumName (Attr.Kind );
463483 if (Attr.Kind == CodeGenIntrinsic::Alignment ||
464484 Attr.Kind == CodeGenIntrinsic::Dereferenceable)
465485 OS << formatv (" Attribute::get(C, Attribute::{0}, {1}),\n " ,
@@ -472,7 +492,8 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
472492 }
473493 OS << R"(
474494 }
475- } // getIntrinsicArgAttributeSet)" ;
495+ } // getIntrinsicArgAttributeSet
496+ )" ;
476497
477498 // Compute unique function attribute sets.
478499 std::map<const CodeGenIntrinsic *, unsigned , FnAttributeComparator>
@@ -481,9 +502,12 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
481502static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
482503 switch (ID) {
483504 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 ;
485509 unsigned ID = UniqFnAttributes.size ();
486- if (!UniqFnAttributes.try_emplace (&Intrinsic , ID).second )
510+ if (!UniqFnAttributes.try_emplace (&Int , ID).second )
487511 continue ;
488512 OS << formatv (R"(
489513 case {0}:
@@ -493,44 +517,42 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
493517 auto addAttribute = [&OS](StringRef Attr) {
494518 OS << formatv (" Attribute::get(C, Attribute::{0}),\n " , Attr);
495519 };
496- if (!Intrinsic .canThrow )
520+ if (!Int .canThrow )
497521 addAttribute (" NoUnwind" );
498- if (Intrinsic .isNoReturn )
522+ if (Int .isNoReturn )
499523 addAttribute (" NoReturn" );
500- if (Intrinsic .isNoCallback )
524+ if (Int .isNoCallback )
501525 addAttribute (" NoCallback" );
502- if (Intrinsic .isNoSync )
526+ if (Int .isNoSync )
503527 addAttribute (" NoSync" );
504- if (Intrinsic .isNoFree )
528+ if (Int .isNoFree )
505529 addAttribute (" NoFree" );
506- if (Intrinsic .isWillReturn )
530+ if (Int .isWillReturn )
507531 addAttribute (" WillReturn" );
508- if (Intrinsic .isCold )
532+ if (Int .isCold )
509533 addAttribute (" Cold" );
510- if (Intrinsic .isNoDuplicate )
534+ if (Int .isNoDuplicate )
511535 addAttribute (" NoDuplicate" );
512- if (Intrinsic .isNoMerge )
536+ if (Int .isNoMerge )
513537 addAttribute (" NoMerge" );
514- if (Intrinsic .isConvergent )
538+ if (Int .isConvergent )
515539 addAttribute (" Convergent" );
516- if (Intrinsic .isSpeculatable )
540+ if (Int .isSpeculatable )
517541 addAttribute (" Speculatable" );
518- if (Intrinsic .isStrictFP )
542+ if (Int .isStrictFP )
519543 addAttribute (" StrictFP" );
520544
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);
525546 if (ME != MemoryEffects::unknown ()) {
526547 OS << formatv (" // {0}\n " , ME);
527548 OS << formatv (" Attribute::getWithMemoryEffects(C, "
528549 " MemoryEffects::createFromIntValue({0})),\n " ,
529550 ME.toIntValue ());
530551 }
531- OS << " });\n " ;
552+ OS << " });" ;
553+ }
554+ OS << R"(
532555 }
533- OS << R"( }
534556} // getIntrinsicFnAttributeSet
535557
536558AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
@@ -585,11 +607,7 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
585607 NumAttrs++, AttrIdx, ArgAttrID);
586608 }
587609
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)) {
593611 unsigned FnAttrID = UniqFnAttributes.find (&Int)->second ;
594612 OS << formatv (" AS[{0}] = {{AttributeList::FunctionIndex, "
595613 " getIntrinsicFnAttributeSet(C, {1})};\n " ,
0 commit comments