@@ -47,6 +47,7 @@ STATISTIC(
47
47
NumWriteArgumentMemOrErrnoMemOnly,
48
48
" Number of functions inferred as memory(argmem: write, errnomem: write)" );
49
49
STATISTIC (NumNoUnwind, " Number of functions inferred as nounwind" );
50
+ STATISTIC (NumNoCallback, " Number of functions inferred as nocallback" );
50
51
STATISTIC (NumNoCapture, " Number of arguments inferred as nocapture" );
51
52
STATISTIC (NumWriteOnlyArg, " Number of arguments inferred as writeonly" );
52
53
STATISTIC (NumReadOnlyArg, " Number of arguments inferred as readonly" );
@@ -148,6 +149,14 @@ static bool setDoesNotThrow(Function &F) {
148
149
return true ;
149
150
}
150
151
152
+ static bool setDoesNotCallback (Function &F) {
153
+ if (F.hasFnAttribute (Attribute::NoCallback))
154
+ return false ;
155
+ F.addFnAttr (Attribute::NoCallback);
156
+ ++NumNoCallback;
157
+ return true ;
158
+ }
159
+
151
160
static bool setRetDoesNotAlias (Function &F) {
152
161
if (F.hasRetAttribute (Attribute::NoAlias))
153
162
return false ;
@@ -322,6 +331,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
322
331
case LibFunc_wcslen:
323
332
Changed |= setOnlyReadsMemory (F);
324
333
Changed |= setDoesNotThrow (F);
334
+ Changed |= setDoesNotCallback (F);
325
335
Changed |= setOnlyAccessesArgMemory (F);
326
336
Changed |= setWillReturn (F);
327
337
Changed |= setDoesNotCapture (F, 0 );
@@ -331,6 +341,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
331
341
Changed |= setOnlyAccessesArgMemory (F);
332
342
Changed |= setOnlyReadsMemory (F);
333
343
Changed |= setDoesNotThrow (F);
344
+ Changed |= setDoesNotCallback (F);
334
345
Changed |= setWillReturn (F);
335
346
break ;
336
347
case LibFunc_strtol:
@@ -341,6 +352,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
341
352
case LibFunc_strtold:
342
353
case LibFunc_strtoull:
343
354
Changed |= setDoesNotThrow (F);
355
+ Changed |= setDoesNotCallback (F);
344
356
Changed |= setWillReturn (F);
345
357
Changed |= setDoesNotCapture (F, 1 );
346
358
Changed |= setOnlyReadsMemory (F, 0 );
@@ -349,6 +361,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
349
361
case LibFunc_strncat:
350
362
Changed |= setOnlyAccessesArgMemory (F);
351
363
Changed |= setDoesNotThrow (F);
364
+ Changed |= setDoesNotCallback (F);
352
365
Changed |= setWillReturn (F);
353
366
Changed |= setReturnedArg (F, 0 );
354
367
Changed |= setDoesNotCapture (F, 1 );
@@ -364,6 +377,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
364
377
case LibFunc_stpncpy:
365
378
Changed |= setOnlyAccessesArgMemory (F);
366
379
Changed |= setDoesNotThrow (F);
380
+ Changed |= setDoesNotCallback (F);
367
381
Changed |= setWillReturn (F);
368
382
Changed |= setDoesNotCapture (F, 1 );
369
383
Changed |= setOnlyWritesMemory (F, 0 );
@@ -373,6 +387,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
373
387
break ;
374
388
case LibFunc_strxfrm:
375
389
Changed |= setDoesNotThrow (F);
390
+ Changed |= setDoesNotCallback (F);
376
391
Changed |= setWillReturn (F);
377
392
Changed |= setDoesNotCapture (F, 0 );
378
393
Changed |= setDoesNotCapture (F, 1 );
@@ -383,6 +398,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
383
398
case LibFunc_strncmp: // 0,1
384
399
case LibFunc_strcspn: // 0,1
385
400
Changed |= setDoesNotThrow (F);
401
+ Changed |= setDoesNotCallback (F);
386
402
Changed |= setOnlyAccessesArgMemory (F);
387
403
Changed |= setWillReturn (F);
388
404
Changed |= setOnlyReadsMemory (F);
@@ -396,6 +412,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
396
412
// global memory.
397
413
Changed |= setOnlyReadsMemory (F);
398
414
Changed |= setDoesNotThrow (F);
415
+ Changed |= setDoesNotCallback (F);
399
416
Changed |= setWillReturn (F);
400
417
Changed |= setDoesNotCapture (F, 0 );
401
418
Changed |= setDoesNotCapture (F, 1 );
@@ -405,12 +422,14 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
405
422
Changed |= setOnlyAccessesArgMemory (F);
406
423
Changed |= setOnlyReadsMemory (F);
407
424
Changed |= setDoesNotThrow (F);
425
+ Changed |= setDoesNotCallback (F);
408
426
Changed |= setWillReturn (F);
409
427
Changed |= setDoesNotCapture (F, 1 );
410
428
break ;
411
429
case LibFunc_strtok:
412
430
case LibFunc_strtok_r:
413
431
Changed |= setDoesNotThrow (F);
432
+ Changed |= setDoesNotCallback (F);
414
433
Changed |= setWillReturn (F);
415
434
Changed |= setDoesNotCapture (F, 1 );
416
435
Changed |= setOnlyReadsMemory (F, 1 );
@@ -509,13 +528,15 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
509
528
Changed |= setOnlyAccessesArgMemory (F);
510
529
Changed |= setOnlyReadsMemory (F);
511
530
Changed |= setDoesNotThrow (F);
531
+ Changed |= setDoesNotCallback (F);
512
532
Changed |= setWillReturn (F);
513
533
Changed |= setDoesNotCapture (F, 0 );
514
534
Changed |= setDoesNotCapture (F, 1 );
515
535
break ;
516
536
case LibFunc_memchr:
517
537
case LibFunc_memrchr:
518
538
Changed |= setDoesNotThrow (F);
539
+ Changed |= setDoesNotCallback (F);
519
540
Changed |= setOnlyAccessesArgMemory (F);
520
541
Changed |= setOnlyReadsMemory (F);
521
542
Changed |= setWillReturn (F);
@@ -524,13 +545,15 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
524
545
case LibFunc_modff:
525
546
case LibFunc_modfl:
526
547
Changed |= setDoesNotThrow (F);
548
+ Changed |= setDoesNotCallback (F);
527
549
Changed |= setWillReturn (F);
528
550
Changed |= setOnlyAccessesArgMemory (F);
529
551
Changed |= setOnlyWritesMemory (F);
530
552
Changed |= setDoesNotCapture (F, 1 );
531
553
break ;
532
554
case LibFunc_memcpy:
533
555
Changed |= setDoesNotThrow (F);
556
+ Changed |= setDoesNotCallback (F);
534
557
Changed |= setOnlyAccessesArgMemory (F);
535
558
Changed |= setWillReturn (F);
536
559
Changed |= setDoesNotAlias (F, 0 );
@@ -542,6 +565,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
542
565
break ;
543
566
case LibFunc_memmove:
544
567
Changed |= setDoesNotThrow (F);
568
+ Changed |= setDoesNotCallback (F);
545
569
Changed |= setOnlyAccessesArgMemory (F);
546
570
Changed |= setWillReturn (F);
547
571
Changed |= setReturnedArg (F, 0 );
@@ -555,6 +579,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
555
579
[[fallthrough]];
556
580
case LibFunc_memcpy_chk:
557
581
Changed |= setDoesNotThrow (F);
582
+ Changed |= setDoesNotCallback (F);
558
583
Changed |= setOnlyAccessesArgMemory (F);
559
584
Changed |= setDoesNotAlias (F, 0 );
560
585
Changed |= setOnlyWritesMemory (F, 0 );
@@ -657,6 +682,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
657
682
break ;
658
683
case LibFunc_bcopy:
659
684
Changed |= setDoesNotThrow (F);
685
+ Changed |= setDoesNotCallback (F);
660
686
Changed |= setOnlyAccessesArgMemory (F);
661
687
Changed |= setWillReturn (F);
662
688
Changed |= setDoesNotCapture (F, 0 );
@@ -666,6 +692,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
666
692
break ;
667
693
case LibFunc_bcmp:
668
694
Changed |= setDoesNotThrow (F);
695
+ Changed |= setDoesNotCallback (F);
669
696
Changed |= setOnlyAccessesArgMemory (F);
670
697
Changed |= setOnlyReadsMemory (F);
671
698
Changed |= setWillReturn (F);
@@ -674,6 +701,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
674
701
break ;
675
702
case LibFunc_bzero:
676
703
Changed |= setDoesNotThrow (F);
704
+ Changed |= setDoesNotCallback (F);
677
705
Changed |= setOnlyAccessesArgMemory (F);
678
706
Changed |= setWillReturn (F);
679
707
Changed |= setDoesNotCapture (F, 0 );
@@ -710,6 +738,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
710
738
case LibFunc_atof:
711
739
case LibFunc_atoll:
712
740
Changed |= setDoesNotThrow (F);
741
+ Changed |= setDoesNotCallback (F);
713
742
Changed |= setOnlyReadsMemory (F);
714
743
Changed |= setWillReturn (F);
715
744
Changed |= setDoesNotCapture (F, 0 );
@@ -787,6 +816,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
787
816
case LibFunc_frexpf:
788
817
case LibFunc_frexpl:
789
818
Changed |= setDoesNotThrow (F);
819
+ Changed |= setDoesNotCallback (F);
790
820
Changed |= setWillReturn (F);
791
821
Changed |= setOnlyAccessesArgMemory (F);
792
822
Changed |= setOnlyWritesMemory (F);
@@ -1025,6 +1055,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
1025
1055
case LibFunc_ntohl:
1026
1056
case LibFunc_ntohs:
1027
1057
Changed |= setDoesNotThrow (F);
1058
+ Changed |= setDoesNotCallback (F);
1028
1059
Changed |= setDoesNotAccessMemory (F);
1029
1060
break ;
1030
1061
case LibFunc_lstat:
@@ -1041,7 +1072,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
1041
1072
Changed |= setOnlyReadsMemory (F, 0 );
1042
1073
break ;
1043
1074
case LibFunc_qsort:
1044
- // May throw; places call through function pointer.
1075
+ // May throw/callback ; places call through function pointer.
1045
1076
// Cannot give undef pointer/size
1046
1077
Changed |= setRetAndArgsNoUndef (F);
1047
1078
Changed |= setDoesNotCapture (F, 3 );
@@ -1058,6 +1089,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
1058
1089
break ;
1059
1090
case LibFunc_dunder_strtok_r:
1060
1091
Changed |= setDoesNotThrow (F);
1092
+ Changed |= setDoesNotCallback (F);
1061
1093
Changed |= setDoesNotCapture (F, 1 );
1062
1094
Changed |= setOnlyReadsMemory (F, 1 );
1063
1095
break ;
@@ -1149,13 +1181,15 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
1149
1181
Changed |= setOnlyAccessesArgMemory (F);
1150
1182
Changed |= setOnlyWritesMemory (F, 0 );
1151
1183
Changed |= setDoesNotThrow (F);
1184
+ Changed |= setDoesNotCallback (F);
1152
1185
break ;
1153
1186
case LibFunc_abort:
1154
1187
Changed |= setIsCold (F);
1155
1188
Changed |= setNoReturn (F);
1156
1189
Changed |= setDoesNotThrow (F);
1157
1190
break ;
1158
1191
case LibFunc_terminate:
1192
+ // May callback; terminate_handler may be called
1159
1193
Changed |= setIsCold (F);
1160
1194
Changed |= setNoReturn (F);
1161
1195
break ;
@@ -1284,6 +1318,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
1284
1318
case LibFunc_tanhl:
1285
1319
case LibFunc_tanl:
1286
1320
Changed |= setDoesNotThrow (F);
1321
+ Changed |= setDoesNotCallback (F);
1287
1322
Changed |= setDoesNotFreeMemory (F);
1288
1323
Changed |= setWillReturn (F);
1289
1324
Changed |= setOnlyWritesErrnoMemory (F);
@@ -1327,6 +1362,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
1327
1362
case LibFunc_isascii:
1328
1363
case LibFunc_isdigit:
1329
1364
Changed |= setDoesNotThrow (F);
1365
+ Changed |= setDoesNotCallback (F);
1330
1366
Changed |= setDoesNotFreeMemory (F);
1331
1367
Changed |= setWillReturn (F);
1332
1368
break ;
@@ -1340,6 +1376,7 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
1340
1376
case LibFunc_remquof:
1341
1377
case LibFunc_remquol:
1342
1378
Changed |= setDoesNotThrow (F);
1379
+ Changed |= setDoesNotCallback (F);
1343
1380
Changed |= setDoesNotFreeMemory (F);
1344
1381
Changed |= setOnlyWritesMemory (F, 2 );
1345
1382
Changed |= setDoesNotCapture (F, 2 );
0 commit comments