llvm.org GIT mirror llvm / d001932
Add a new attribute: norecurse This attribute allows the compiler to assume that the function never recurses into itself, either directly or indirectly (transitively). This can be used among other things to demote global variables to locals. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252282 91177308-0d34-0410-b5e6-96231b3b80d8 James Molloy 4 years ago
19 changed file(s) with 49 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
12761276 This function attribute indicates that the function never returns
12771277 normally. This produces undefined behavior at runtime if the
12781278 function ever does dynamically return.
1279 ``norecurse``
1280 This function attribute indicates that the function does not call itself
1281 either directly or indirectly down any possible call path. This produces
1282 undefined behavior at runtime if the function ever does recurse.
12791283 ``nounwind``
12801284 This function attribute indicates that the function never raises an
12811285 exception. If the function does raise an exception, its runtime
465465 ATTR_KIND_SAFESTACK = 44,
466466 ATTR_KIND_ARGMEMONLY = 45,
467467 ATTR_KIND_SWIFT_SELF = 46,
468 ATTR_KIND_SWIFT_ERROR = 47
468 ATTR_KIND_SWIFT_ERROR = 47,
469 ATTR_KIND_NO_RECURSE = 48
469470 };
470471
471472 enum ComdatSelectionKindCodes {
8585 NoDuplicate, ///< Call cannot be duplicated
8686 NoImplicitFloat, ///< Disable implicit floating point insts
8787 NoInline, ///< inline=never
88 NoRecurse, ///< The function does not recurse
8889 NonLazyBind, ///< Function is called early and/or
8990 ///< often, so lazy binding isn't worthwhile
9091 NonNull, ///< Pointer is known to be not null
328328 addFnAttr(Attribute::Convergent);
329329 }
330330
331 /// Determine if the function is known not to recurse, directly or
332 /// indirectly.
333 bool doesNotRecurse() const {
334 return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
335 Attribute::NoRecurse);
336 }
337 void setDoesNotRecurse() {
338 addFnAttr(Attribute::NoRecurse);
339 }
331340
332341 /// @brief True if the ABI mandates (or the user requested) that this
333342 /// function be in a unwind table.
615615 KEYWORD(noduplicate);
616616 KEYWORD(noimplicitfloat);
617617 KEYWORD(noinline);
618 KEYWORD(norecurse);
618619 KEYWORD(nonlazybind);
619620 KEYWORD(nonnull);
620621 KEYWORD(noredzone);
997997 case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
998998 case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
999999 case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
1000 case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break;
10001001 case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
10011002 case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break;
10021003 case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
122122 kw_noduplicate,
123123 kw_noimplicitfloat,
124124 kw_noinline,
125 kw_norecurse,
125126 kw_nonlazybind,
126127 kw_nonnull,
127128 kw_noredzone,
13041304 return Attribute::NoImplicitFloat;
13051305 case bitc::ATTR_KIND_NO_INLINE:
13061306 return Attribute::NoInline;
1307 case bitc::ATTR_KIND_NO_RECURSE:
1308 return Attribute::NoRecurse;
13071309 case bitc::ATTR_KIND_NON_LAZY_BIND:
13081310 return Attribute::NonLazyBind;
13091311 case bitc::ATTR_KIND_NON_NULL:
201201 return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT;
202202 case Attribute::NoInline:
203203 return bitc::ATTR_KIND_NO_INLINE;
204 case Attribute::NoRecurse:
205 return bitc::ATTR_KIND_NO_RECURSE;
204206 case Attribute::NonLazyBind:
205207 return bitc::ATTR_KIND_NON_LAZY_BIND;
206208 case Attribute::NonNull:
231231 return "noredzone";
232232 if (hasAttribute(Attribute::NoReturn))
233233 return "noreturn";
234 if (hasAttribute(Attribute::NoRecurse))
235 return "norecurse";
234236 if (hasAttribute(Attribute::NoUnwind))
235237 return "nounwind";
236238 if (hasAttribute(Attribute::OptimizeNone))
441443 case Attribute::JumpTable: return 1ULL << 45;
442444 case Attribute::Convergent: return 1ULL << 46;
443445 case Attribute::SafeStack: return 1ULL << 47;
446 case Attribute::NoRecurse: return 1ULL << 48;
444447 case Attribute::Dereferenceable:
445448 llvm_unreachable("dereferenceable attribute not supported in raw format");
446449 break;
12321232 I->getKindAsEnum() == Attribute::OptimizeNone ||
12331233 I->getKindAsEnum() == Attribute::JumpTable ||
12341234 I->getKindAsEnum() == Attribute::Convergent ||
1235 I->getKindAsEnum() == Attribute::ArgMemOnly) {
1235 I->getKindAsEnum() == Attribute::ArgMemOnly ||
1236 I->getKindAsEnum() == Attribute::NoRecurse) {
12361237 if (!isFunction) {
12371238 CheckFailed("Attribute '" + I->getAsString() +
12381239 "' only applies to functions!", V);
0 ; RUN: not llvm-c-test --module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
11
2 CHECK: Error parsing bitcode: Unknown attribute kind (48)
2 CHECK: Error parsing bitcode: Unknown attribute kind (50)
203203 ; CHECK: define void @f34()
204204 {
205205 call void @nobuiltin() nobuiltin
206 ; CHECK: call void @nobuiltin() #27
206 ; CHECK: call void @nobuiltin() #28
207207 ret void;
208208 }
209209
268268
269269 ; CHECK: define "string_attribute_with_value"="value" void @f46(i32 "string_attribute_with_value"="value")
270270 define "string_attribute_with_value"="value" void @f46(i32 "string_attribute_with_value"="value") {
271 ret void
272 }
273
274 ; CHECK: define void @f47() #27
275 define void @f47() norecurse {
271276 ret void
272277 }
273278
298303 ; CHECK: attributes #24 = { jumptable }
299304 ; CHECK: attributes #25 = { convergent }
300305 ; CHECK: attributes #26 = { argmemonly }
301 ; CHECK: attributes #27 = { nobuiltin }
306 ; CHECK: attributes #27 = { norecurse }
307 ; CHECK: attributes #28 = { nobuiltin }
500500 ; CHECK: declare void @f.uwtable() #30
501501 declare void @f.kvpair() "cpu"="cortex-a8"
502502 ; CHECK:declare void @f.kvpair() #31
503 declare void @f.norecurse() norecurse
504 ; CHECK: declare void @f.norecurse() #32
503505
504506 ; Functions -- section
505507 declare void @f.section() section "80"
558560
559561 ; Functions -- Personality constant
560562 declare void @llvm.donothing() nounwind readnone
561 ; CHECK: declare void @llvm.donothing() #32
563 ; CHECK: declare void @llvm.donothing() #33
562564 define void @f.no_personality() personality i8 3 {
563565 ; CHECK: define void @f.no_personality() personality i8 3
564566 invoke void @llvm.donothing() to label %normal unwind label %exception
11241126 ; CHECK: select <2 x i1> , <2 x i8> , <2 x i8>
11251127
11261128 call void @f.nobuiltin() builtin
1127 ; CHECK: call void @f.nobuiltin() #36
1129 ; CHECK: call void @f.nobuiltin() #37
11281130
11291131 call fastcc noalias i32* @f.noalias() noinline
11301132 ; CHECK: call fastcc noalias i32* @f.noalias() #12
14961498 ; CHECK: attributes #29 = { "thunk" }
14971499 ; CHECK: attributes #30 = { uwtable }
14981500 ; CHECK: attributes #31 = { "cpu"="cortex-a8" }
1499 ; CHECK: attributes #32 = { nounwind readnone }
1500 ; CHECK: attributes #33 = { nounwind readonly argmemonly }
1501 ; CHECK: attributes #34 = { nounwind argmemonly }
1502 ; CHECK: attributes #35 = { nounwind readonly }
1503 ; CHECK: attributes #36 = { builtin }
1501 ; CHECK: attributes #32 = { norecurse }
1502 ; CHECK: attributes #33 = { nounwind readnone }
1503 ; CHECK: attributes #34 = { nounwind readonly argmemonly }
1504 ; CHECK: attributes #35 = { nounwind argmemonly }
1505 ; CHECK: attributes #36 = { nounwind readonly }
1506 ; CHECK: attributes #37 = { builtin }
15041507
15051508 ;; Metadata
15061509
0 ; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s
11
2 ; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (48)
2 ; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (50)
33
44 ; invalid.ll.bc has an invalid attribute number.
55 ; The test checks that LLVM reports the error and doesn't access freed memory
Binary diff not shown
0 ; RUN: not llvm-lto %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
11
22
3 ; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (48)
3 ; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (50)