1 //===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements some functions that will create standard C libcalls.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Transforms/Utils/BuildLibCalls.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/Analysis/TargetLibraryInfo.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/DataLayout.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/IR/IRBuilder.h"
22 #include "llvm/IR/Intrinsics.h"
23 #include "llvm/IR/LLVMContext.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/IR/Type.h"
26
27 using namespace llvm;
28
29 #define DEBUG_TYPE "build-libcalls"
30
31 //- Infer Attributes ---------------------------------------------------------//
32
33 STATISTIC(NumReadNone, "Number of functions inferred as readnone");
34 STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
35 STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
36 STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
37 STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
38 STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
39 STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
40 STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
41 STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");
42
setDoesNotAccessMemory(Function & F)43 static bool setDoesNotAccessMemory(Function &F) {
44 if (F.doesNotAccessMemory())
45 return false;
46 F.setDoesNotAccessMemory();
47 ++NumReadNone;
48 return true;
49 }
50
setOnlyReadsMemory(Function & F)51 static bool setOnlyReadsMemory(Function &F) {
52 if (F.onlyReadsMemory())
53 return false;
54 F.setOnlyReadsMemory();
55 ++NumReadOnly;
56 return true;
57 }
58
setOnlyAccessesArgMemory(Function & F)59 static bool setOnlyAccessesArgMemory(Function &F) {
60 if (F.onlyAccessesArgMemory())
61 return false;
62 F.setOnlyAccessesArgMemory();
63 ++NumArgMemOnly;
64 return true;
65 }
66
setDoesNotThrow(Function & F)67 static bool setDoesNotThrow(Function &F) {
68 if (F.doesNotThrow())
69 return false;
70 F.setDoesNotThrow();
71 ++NumNoUnwind;
72 return true;
73 }
74
setRetDoesNotAlias(Function & F)75 static bool setRetDoesNotAlias(Function &F) {
76 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias))
77 return false;
78 F.addAttribute(AttributeList::ReturnIndex, Attribute::NoAlias);
79 ++NumNoAlias;
80 return true;
81 }
82
setDoesNotCapture(Function & F,unsigned ArgNo)83 static bool setDoesNotCapture(Function &F, unsigned ArgNo) {
84 if (F.hasParamAttribute(ArgNo, Attribute::NoCapture))
85 return false;
86 F.addParamAttr(ArgNo, Attribute::NoCapture);
87 ++NumNoCapture;
88 return true;
89 }
90
setOnlyReadsMemory(Function & F,unsigned ArgNo)91 static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
92 if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
93 return false;
94 F.addParamAttr(ArgNo, Attribute::ReadOnly);
95 ++NumReadOnlyArg;
96 return true;
97 }
98
setRetNonNull(Function & F)99 static bool setRetNonNull(Function &F) {
100 assert(F.getReturnType()->isPointerTy() &&
101 "nonnull applies only to pointers");
102 if (F.hasAttribute(AttributeList::ReturnIndex, Attribute::NonNull))
103 return false;
104 F.addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
105 ++NumNonNull;
106 return true;
107 }
108
setReturnedArg(Function & F,unsigned ArgNo)109 static bool setReturnedArg(Function &F, unsigned ArgNo) {
110 if (F.hasParamAttribute(ArgNo, Attribute::Returned))
111 return false;
112 F.addParamAttr(ArgNo, Attribute::Returned);
113 ++NumReturnedArg;
114 return true;
115 }
116
setNonLazyBind(Function & F)117 static bool setNonLazyBind(Function &F) {
118 if (F.hasFnAttribute(Attribute::NonLazyBind))
119 return false;
120 F.addFnAttr(Attribute::NonLazyBind);
121 return true;
122 }
123
inferLibFuncAttributes(Module * M,StringRef Name,const TargetLibraryInfo & TLI)124 bool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
125 const TargetLibraryInfo &TLI) {
126 Function *F = M->getFunction(Name);
127 if (!F)
128 return false;
129 return inferLibFuncAttributes(*F, TLI);
130 }
131
inferLibFuncAttributes(Function & F,const TargetLibraryInfo & TLI)132 bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
133 LibFunc TheLibFunc;
134 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
135 return false;
136
137 bool Changed = false;
138
139 if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
140 Changed |= setNonLazyBind(F);
141
142 switch (TheLibFunc) {
143 case LibFunc_strlen:
144 case LibFunc_wcslen:
145 Changed |= setOnlyReadsMemory(F);
146 Changed |= setDoesNotThrow(F);
147 Changed |= setOnlyAccessesArgMemory(F);
148 Changed |= setDoesNotCapture(F, 0);
149 return Changed;
150 case LibFunc_strchr:
151 case LibFunc_strrchr:
152 Changed |= setOnlyReadsMemory(F);
153 Changed |= setDoesNotThrow(F);
154 return Changed;
155 case LibFunc_strtol:
156 case LibFunc_strtod:
157 case LibFunc_strtof:
158 case LibFunc_strtoul:
159 case LibFunc_strtoll:
160 case LibFunc_strtold:
161 case LibFunc_strtoull:
162 Changed |= setDoesNotThrow(F);
163 Changed |= setDoesNotCapture(F, 1);
164 Changed |= setOnlyReadsMemory(F, 0);
165 return Changed;
166 case LibFunc_strcpy:
167 case LibFunc_strncpy:
168 case LibFunc_strcat:
169 case LibFunc_strncat:
170 Changed |= setReturnedArg(F, 0);
171 LLVM_FALLTHROUGH;
172 case LibFunc_stpcpy:
173 case LibFunc_stpncpy:
174 Changed |= setDoesNotThrow(F);
175 Changed |= setDoesNotCapture(F, 1);
176 Changed |= setOnlyReadsMemory(F, 1);
177 return Changed;
178 case LibFunc_strxfrm:
179 Changed |= setDoesNotThrow(F);
180 Changed |= setDoesNotCapture(F, 0);
181 Changed |= setDoesNotCapture(F, 1);
182 Changed |= setOnlyReadsMemory(F, 1);
183 return Changed;
184 case LibFunc_strcmp: // 0,1
185 case LibFunc_strspn: // 0,1
186 case LibFunc_strncmp: // 0,1
187 case LibFunc_strcspn: // 0,1
188 case LibFunc_strcoll: // 0,1
189 case LibFunc_strcasecmp: // 0,1
190 case LibFunc_strncasecmp: //
191 Changed |= setOnlyReadsMemory(F);
192 Changed |= setDoesNotThrow(F);
193 Changed |= setDoesNotCapture(F, 0);
194 Changed |= setDoesNotCapture(F, 1);
195 return Changed;
196 case LibFunc_strstr:
197 case LibFunc_strpbrk:
198 Changed |= setOnlyReadsMemory(F);
199 Changed |= setDoesNotThrow(F);
200 Changed |= setDoesNotCapture(F, 1);
201 return Changed;
202 case LibFunc_strtok:
203 case LibFunc_strtok_r:
204 Changed |= setDoesNotThrow(F);
205 Changed |= setDoesNotCapture(F, 1);
206 Changed |= setOnlyReadsMemory(F, 1);
207 return Changed;
208 case LibFunc_scanf:
209 Changed |= setDoesNotThrow(F);
210 Changed |= setDoesNotCapture(F, 0);
211 Changed |= setOnlyReadsMemory(F, 0);
212 return Changed;
213 case LibFunc_setbuf:
214 case LibFunc_setvbuf:
215 Changed |= setDoesNotThrow(F);
216 Changed |= setDoesNotCapture(F, 0);
217 return Changed;
218 case LibFunc_strdup:
219 case LibFunc_strndup:
220 Changed |= setDoesNotThrow(F);
221 Changed |= setRetDoesNotAlias(F);
222 Changed |= setDoesNotCapture(F, 0);
223 Changed |= setOnlyReadsMemory(F, 0);
224 return Changed;
225 case LibFunc_stat:
226 case LibFunc_statvfs:
227 Changed |= setDoesNotThrow(F);
228 Changed |= setDoesNotCapture(F, 0);
229 Changed |= setDoesNotCapture(F, 1);
230 Changed |= setOnlyReadsMemory(F, 0);
231 return Changed;
232 case LibFunc_sscanf:
233 Changed |= setDoesNotThrow(F);
234 Changed |= setDoesNotCapture(F, 0);
235 Changed |= setDoesNotCapture(F, 1);
236 Changed |= setOnlyReadsMemory(F, 0);
237 Changed |= setOnlyReadsMemory(F, 1);
238 return Changed;
239 case LibFunc_sprintf:
240 Changed |= setDoesNotThrow(F);
241 Changed |= setDoesNotCapture(F, 0);
242 Changed |= setDoesNotCapture(F, 1);
243 Changed |= setOnlyReadsMemory(F, 1);
244 return Changed;
245 case LibFunc_snprintf:
246 Changed |= setDoesNotThrow(F);
247 Changed |= setDoesNotCapture(F, 0);
248 Changed |= setDoesNotCapture(F, 2);
249 Changed |= setOnlyReadsMemory(F, 2);
250 return Changed;
251 case LibFunc_setitimer:
252 Changed |= setDoesNotThrow(F);
253 Changed |= setDoesNotCapture(F, 1);
254 Changed |= setDoesNotCapture(F, 2);
255 Changed |= setOnlyReadsMemory(F, 1);
256 return Changed;
257 case LibFunc_system:
258 // May throw; "system" is a valid pthread cancellation point.
259 Changed |= setDoesNotCapture(F, 0);
260 Changed |= setOnlyReadsMemory(F, 0);
261 return Changed;
262 case LibFunc_malloc:
263 Changed |= setDoesNotThrow(F);
264 Changed |= setRetDoesNotAlias(F);
265 return Changed;
266 case LibFunc_memcmp:
267 Changed |= setOnlyReadsMemory(F);
268 Changed |= setDoesNotThrow(F);
269 Changed |= setDoesNotCapture(F, 0);
270 Changed |= setDoesNotCapture(F, 1);
271 return Changed;
272 case LibFunc_memchr:
273 case LibFunc_memrchr:
274 Changed |= setOnlyReadsMemory(F);
275 Changed |= setDoesNotThrow(F);
276 return Changed;
277 case LibFunc_modf:
278 case LibFunc_modff:
279 case LibFunc_modfl:
280 Changed |= setDoesNotThrow(F);
281 Changed |= setDoesNotCapture(F, 1);
282 return Changed;
283 case LibFunc_memcpy:
284 case LibFunc_memmove:
285 Changed |= setReturnedArg(F, 0);
286 LLVM_FALLTHROUGH;
287 case LibFunc_mempcpy:
288 case LibFunc_memccpy:
289 Changed |= setDoesNotThrow(F);
290 Changed |= setDoesNotCapture(F, 1);
291 Changed |= setOnlyReadsMemory(F, 1);
292 return Changed;
293 case LibFunc_memcpy_chk:
294 Changed |= setDoesNotThrow(F);
295 return Changed;
296 case LibFunc_memalign:
297 Changed |= setRetDoesNotAlias(F);
298 return Changed;
299 case LibFunc_mkdir:
300 Changed |= setDoesNotThrow(F);
301 Changed |= setDoesNotCapture(F, 0);
302 Changed |= setOnlyReadsMemory(F, 0);
303 return Changed;
304 case LibFunc_mktime:
305 Changed |= setDoesNotThrow(F);
306 Changed |= setDoesNotCapture(F, 0);
307 return Changed;
308 case LibFunc_realloc:
309 Changed |= setDoesNotThrow(F);
310 Changed |= setRetDoesNotAlias(F);
311 Changed |= setDoesNotCapture(F, 0);
312 return Changed;
313 case LibFunc_read:
314 // May throw; "read" is a valid pthread cancellation point.
315 Changed |= setDoesNotCapture(F, 1);
316 return Changed;
317 case LibFunc_rewind:
318 Changed |= setDoesNotThrow(F);
319 Changed |= setDoesNotCapture(F, 0);
320 return Changed;
321 case LibFunc_rmdir:
322 case LibFunc_remove:
323 case LibFunc_realpath:
324 Changed |= setDoesNotThrow(F);
325 Changed |= setDoesNotCapture(F, 0);
326 Changed |= setOnlyReadsMemory(F, 0);
327 return Changed;
328 case LibFunc_rename:
329 Changed |= setDoesNotThrow(F);
330 Changed |= setDoesNotCapture(F, 0);
331 Changed |= setDoesNotCapture(F, 1);
332 Changed |= setOnlyReadsMemory(F, 0);
333 Changed |= setOnlyReadsMemory(F, 1);
334 return Changed;
335 case LibFunc_readlink:
336 Changed |= setDoesNotThrow(F);
337 Changed |= setDoesNotCapture(F, 0);
338 Changed |= setDoesNotCapture(F, 1);
339 Changed |= setOnlyReadsMemory(F, 0);
340 return Changed;
341 case LibFunc_write:
342 // May throw; "write" is a valid pthread cancellation point.
343 Changed |= setDoesNotCapture(F, 1);
344 Changed |= setOnlyReadsMemory(F, 1);
345 return Changed;
346 case LibFunc_bcopy:
347 Changed |= setDoesNotThrow(F);
348 Changed |= setDoesNotCapture(F, 0);
349 Changed |= setDoesNotCapture(F, 1);
350 Changed |= setOnlyReadsMemory(F, 0);
351 return Changed;
352 case LibFunc_bcmp:
353 Changed |= setDoesNotThrow(F);
354 Changed |= setOnlyReadsMemory(F);
355 Changed |= setDoesNotCapture(F, 0);
356 Changed |= setDoesNotCapture(F, 1);
357 return Changed;
358 case LibFunc_bzero:
359 Changed |= setDoesNotThrow(F);
360 Changed |= setDoesNotCapture(F, 0);
361 return Changed;
362 case LibFunc_calloc:
363 Changed |= setDoesNotThrow(F);
364 Changed |= setRetDoesNotAlias(F);
365 return Changed;
366 case LibFunc_chmod:
367 case LibFunc_chown:
368 Changed |= setDoesNotThrow(F);
369 Changed |= setDoesNotCapture(F, 0);
370 Changed |= setOnlyReadsMemory(F, 0);
371 return Changed;
372 case LibFunc_ctermid:
373 case LibFunc_clearerr:
374 case LibFunc_closedir:
375 Changed |= setDoesNotThrow(F);
376 Changed |= setDoesNotCapture(F, 0);
377 return Changed;
378 case LibFunc_atoi:
379 case LibFunc_atol:
380 case LibFunc_atof:
381 case LibFunc_atoll:
382 Changed |= setDoesNotThrow(F);
383 Changed |= setOnlyReadsMemory(F);
384 Changed |= setDoesNotCapture(F, 0);
385 return Changed;
386 case LibFunc_access:
387 Changed |= setDoesNotThrow(F);
388 Changed |= setDoesNotCapture(F, 0);
389 Changed |= setOnlyReadsMemory(F, 0);
390 return Changed;
391 case LibFunc_fopen:
392 Changed |= setDoesNotThrow(F);
393 Changed |= setRetDoesNotAlias(F);
394 Changed |= setDoesNotCapture(F, 0);
395 Changed |= setDoesNotCapture(F, 1);
396 Changed |= setOnlyReadsMemory(F, 0);
397 Changed |= setOnlyReadsMemory(F, 1);
398 return Changed;
399 case LibFunc_fdopen:
400 Changed |= setDoesNotThrow(F);
401 Changed |= setRetDoesNotAlias(F);
402 Changed |= setDoesNotCapture(F, 1);
403 Changed |= setOnlyReadsMemory(F, 1);
404 return Changed;
405 case LibFunc_feof:
406 case LibFunc_free:
407 case LibFunc_fseek:
408 case LibFunc_ftell:
409 case LibFunc_fgetc:
410 case LibFunc_fgetc_unlocked:
411 case LibFunc_fseeko:
412 case LibFunc_ftello:
413 case LibFunc_fileno:
414 case LibFunc_fflush:
415 case LibFunc_fclose:
416 case LibFunc_fsetpos:
417 case LibFunc_flockfile:
418 case LibFunc_funlockfile:
419 case LibFunc_ftrylockfile:
420 Changed |= setDoesNotThrow(F);
421 Changed |= setDoesNotCapture(F, 0);
422 return Changed;
423 case LibFunc_ferror:
424 Changed |= setDoesNotThrow(F);
425 Changed |= setDoesNotCapture(F, 0);
426 Changed |= setOnlyReadsMemory(F);
427 return Changed;
428 case LibFunc_fputc:
429 case LibFunc_fputc_unlocked:
430 case LibFunc_fstat:
431 case LibFunc_frexp:
432 case LibFunc_frexpf:
433 case LibFunc_frexpl:
434 case LibFunc_fstatvfs:
435 Changed |= setDoesNotThrow(F);
436 Changed |= setDoesNotCapture(F, 1);
437 return Changed;
438 case LibFunc_fgets:
439 case LibFunc_fgets_unlocked:
440 Changed |= setDoesNotThrow(F);
441 Changed |= setDoesNotCapture(F, 2);
442 return Changed;
443 case LibFunc_fread:
444 case LibFunc_fread_unlocked:
445 Changed |= setDoesNotThrow(F);
446 Changed |= setDoesNotCapture(F, 0);
447 Changed |= setDoesNotCapture(F, 3);
448 return Changed;
449 case LibFunc_fwrite:
450 case LibFunc_fwrite_unlocked:
451 Changed |= setDoesNotThrow(F);
452 Changed |= setDoesNotCapture(F, 0);
453 Changed |= setDoesNotCapture(F, 3);
454 // FIXME: readonly #1?
455 return Changed;
456 case LibFunc_fputs:
457 case LibFunc_fputs_unlocked:
458 Changed |= setDoesNotThrow(F);
459 Changed |= setDoesNotCapture(F, 0);
460 Changed |= setDoesNotCapture(F, 1);
461 Changed |= setOnlyReadsMemory(F, 0);
462 return Changed;
463 case LibFunc_fscanf:
464 case LibFunc_fprintf:
465 Changed |= setDoesNotThrow(F);
466 Changed |= setDoesNotCapture(F, 0);
467 Changed |= setDoesNotCapture(F, 1);
468 Changed |= setOnlyReadsMemory(F, 1);
469 return Changed;
470 case LibFunc_fgetpos:
471 Changed |= setDoesNotThrow(F);
472 Changed |= setDoesNotCapture(F, 0);
473 Changed |= setDoesNotCapture(F, 1);
474 return Changed;
475 case LibFunc_getc:
476 case LibFunc_getlogin_r:
477 case LibFunc_getc_unlocked:
478 Changed |= setDoesNotThrow(F);
479 Changed |= setDoesNotCapture(F, 0);
480 return Changed;
481 case LibFunc_getenv:
482 Changed |= setDoesNotThrow(F);
483 Changed |= setOnlyReadsMemory(F);
484 Changed |= setDoesNotCapture(F, 0);
485 return Changed;
486 case LibFunc_gets:
487 case LibFunc_getchar:
488 case LibFunc_getchar_unlocked:
489 Changed |= setDoesNotThrow(F);
490 return Changed;
491 case LibFunc_getitimer:
492 Changed |= setDoesNotThrow(F);
493 Changed |= setDoesNotCapture(F, 1);
494 return Changed;
495 case LibFunc_getpwnam:
496 Changed |= setDoesNotThrow(F);
497 Changed |= setDoesNotCapture(F, 0);
498 Changed |= setOnlyReadsMemory(F, 0);
499 return Changed;
500 case LibFunc_ungetc:
501 Changed |= setDoesNotThrow(F);
502 Changed |= setDoesNotCapture(F, 1);
503 return Changed;
504 case LibFunc_uname:
505 Changed |= setDoesNotThrow(F);
506 Changed |= setDoesNotCapture(F, 0);
507 return Changed;
508 case LibFunc_unlink:
509 Changed |= setDoesNotThrow(F);
510 Changed |= setDoesNotCapture(F, 0);
511 Changed |= setOnlyReadsMemory(F, 0);
512 return Changed;
513 case LibFunc_unsetenv:
514 Changed |= setDoesNotThrow(F);
515 Changed |= setDoesNotCapture(F, 0);
516 Changed |= setOnlyReadsMemory(F, 0);
517 return Changed;
518 case LibFunc_utime:
519 case LibFunc_utimes:
520 Changed |= setDoesNotThrow(F);
521 Changed |= setDoesNotCapture(F, 0);
522 Changed |= setDoesNotCapture(F, 1);
523 Changed |= setOnlyReadsMemory(F, 0);
524 Changed |= setOnlyReadsMemory(F, 1);
525 return Changed;
526 case LibFunc_putc:
527 case LibFunc_putc_unlocked:
528 Changed |= setDoesNotThrow(F);
529 Changed |= setDoesNotCapture(F, 1);
530 return Changed;
531 case LibFunc_puts:
532 case LibFunc_printf:
533 case LibFunc_perror:
534 Changed |= setDoesNotThrow(F);
535 Changed |= setDoesNotCapture(F, 0);
536 Changed |= setOnlyReadsMemory(F, 0);
537 return Changed;
538 case LibFunc_pread:
539 // May throw; "pread" is a valid pthread cancellation point.
540 Changed |= setDoesNotCapture(F, 1);
541 return Changed;
542 case LibFunc_pwrite:
543 // May throw; "pwrite" is a valid pthread cancellation point.
544 Changed |= setDoesNotCapture(F, 1);
545 Changed |= setOnlyReadsMemory(F, 1);
546 return Changed;
547 case LibFunc_putchar:
548 case LibFunc_putchar_unlocked:
549 Changed |= setDoesNotThrow(F);
550 return Changed;
551 case LibFunc_popen:
552 Changed |= setDoesNotThrow(F);
553 Changed |= setRetDoesNotAlias(F);
554 Changed |= setDoesNotCapture(F, 0);
555 Changed |= setDoesNotCapture(F, 1);
556 Changed |= setOnlyReadsMemory(F, 0);
557 Changed |= setOnlyReadsMemory(F, 1);
558 return Changed;
559 case LibFunc_pclose:
560 Changed |= setDoesNotThrow(F);
561 Changed |= setDoesNotCapture(F, 0);
562 return Changed;
563 case LibFunc_vscanf:
564 Changed |= setDoesNotThrow(F);
565 Changed |= setDoesNotCapture(F, 0);
566 Changed |= setOnlyReadsMemory(F, 0);
567 return Changed;
568 case LibFunc_vsscanf:
569 Changed |= setDoesNotThrow(F);
570 Changed |= setDoesNotCapture(F, 0);
571 Changed |= setDoesNotCapture(F, 1);
572 Changed |= setOnlyReadsMemory(F, 0);
573 Changed |= setOnlyReadsMemory(F, 1);
574 return Changed;
575 case LibFunc_vfscanf:
576 Changed |= setDoesNotThrow(F);
577 Changed |= setDoesNotCapture(F, 0);
578 Changed |= setDoesNotCapture(F, 1);
579 Changed |= setOnlyReadsMemory(F, 1);
580 return Changed;
581 case LibFunc_valloc:
582 Changed |= setDoesNotThrow(F);
583 Changed |= setRetDoesNotAlias(F);
584 return Changed;
585 case LibFunc_vprintf:
586 Changed |= setDoesNotThrow(F);
587 Changed |= setDoesNotCapture(F, 0);
588 Changed |= setOnlyReadsMemory(F, 0);
589 return Changed;
590 case LibFunc_vfprintf:
591 case LibFunc_vsprintf:
592 Changed |= setDoesNotThrow(F);
593 Changed |= setDoesNotCapture(F, 0);
594 Changed |= setDoesNotCapture(F, 1);
595 Changed |= setOnlyReadsMemory(F, 1);
596 return Changed;
597 case LibFunc_vsnprintf:
598 Changed |= setDoesNotThrow(F);
599 Changed |= setDoesNotCapture(F, 0);
600 Changed |= setDoesNotCapture(F, 2);
601 Changed |= setOnlyReadsMemory(F, 2);
602 return Changed;
603 case LibFunc_open:
604 // May throw; "open" is a valid pthread cancellation point.
605 Changed |= setDoesNotCapture(F, 0);
606 Changed |= setOnlyReadsMemory(F, 0);
607 return Changed;
608 case LibFunc_opendir:
609 Changed |= setDoesNotThrow(F);
610 Changed |= setRetDoesNotAlias(F);
611 Changed |= setDoesNotCapture(F, 0);
612 Changed |= setOnlyReadsMemory(F, 0);
613 return Changed;
614 case LibFunc_tmpfile:
615 Changed |= setDoesNotThrow(F);
616 Changed |= setRetDoesNotAlias(F);
617 return Changed;
618 case LibFunc_times:
619 Changed |= setDoesNotThrow(F);
620 Changed |= setDoesNotCapture(F, 0);
621 return Changed;
622 case LibFunc_htonl:
623 case LibFunc_htons:
624 case LibFunc_ntohl:
625 case LibFunc_ntohs:
626 Changed |= setDoesNotThrow(F);
627 Changed |= setDoesNotAccessMemory(F);
628 return Changed;
629 case LibFunc_lstat:
630 Changed |= setDoesNotThrow(F);
631 Changed |= setDoesNotCapture(F, 0);
632 Changed |= setDoesNotCapture(F, 1);
633 Changed |= setOnlyReadsMemory(F, 0);
634 return Changed;
635 case LibFunc_lchown:
636 Changed |= setDoesNotThrow(F);
637 Changed |= setDoesNotCapture(F, 0);
638 Changed |= setOnlyReadsMemory(F, 0);
639 return Changed;
640 case LibFunc_qsort:
641 // May throw; places call through function pointer.
642 Changed |= setDoesNotCapture(F, 3);
643 return Changed;
644 case LibFunc_dunder_strdup:
645 case LibFunc_dunder_strndup:
646 Changed |= setDoesNotThrow(F);
647 Changed |= setRetDoesNotAlias(F);
648 Changed |= setDoesNotCapture(F, 0);
649 Changed |= setOnlyReadsMemory(F, 0);
650 return Changed;
651 case LibFunc_dunder_strtok_r:
652 Changed |= setDoesNotThrow(F);
653 Changed |= setDoesNotCapture(F, 1);
654 Changed |= setOnlyReadsMemory(F, 1);
655 return Changed;
656 case LibFunc_under_IO_getc:
657 Changed |= setDoesNotThrow(F);
658 Changed |= setDoesNotCapture(F, 0);
659 return Changed;
660 case LibFunc_under_IO_putc:
661 Changed |= setDoesNotThrow(F);
662 Changed |= setDoesNotCapture(F, 1);
663 return Changed;
664 case LibFunc_dunder_isoc99_scanf:
665 Changed |= setDoesNotThrow(F);
666 Changed |= setDoesNotCapture(F, 0);
667 Changed |= setOnlyReadsMemory(F, 0);
668 return Changed;
669 case LibFunc_stat64:
670 case LibFunc_lstat64:
671 case LibFunc_statvfs64:
672 Changed |= setDoesNotThrow(F);
673 Changed |= setDoesNotCapture(F, 0);
674 Changed |= setDoesNotCapture(F, 1);
675 Changed |= setOnlyReadsMemory(F, 0);
676 return Changed;
677 case LibFunc_dunder_isoc99_sscanf:
678 Changed |= setDoesNotThrow(F);
679 Changed |= setDoesNotCapture(F, 0);
680 Changed |= setDoesNotCapture(F, 1);
681 Changed |= setOnlyReadsMemory(F, 0);
682 Changed |= setOnlyReadsMemory(F, 1);
683 return Changed;
684 case LibFunc_fopen64:
685 Changed |= setDoesNotThrow(F);
686 Changed |= setRetDoesNotAlias(F);
687 Changed |= setDoesNotCapture(F, 0);
688 Changed |= setDoesNotCapture(F, 1);
689 Changed |= setOnlyReadsMemory(F, 0);
690 Changed |= setOnlyReadsMemory(F, 1);
691 return Changed;
692 case LibFunc_fseeko64:
693 case LibFunc_ftello64:
694 Changed |= setDoesNotThrow(F);
695 Changed |= setDoesNotCapture(F, 0);
696 return Changed;
697 case LibFunc_tmpfile64:
698 Changed |= setDoesNotThrow(F);
699 Changed |= setRetDoesNotAlias(F);
700 return Changed;
701 case LibFunc_fstat64:
702 case LibFunc_fstatvfs64:
703 Changed |= setDoesNotThrow(F);
704 Changed |= setDoesNotCapture(F, 1);
705 return Changed;
706 case LibFunc_open64:
707 // May throw; "open" is a valid pthread cancellation point.
708 Changed |= setDoesNotCapture(F, 0);
709 Changed |= setOnlyReadsMemory(F, 0);
710 return Changed;
711 case LibFunc_gettimeofday:
712 // Currently some platforms have the restrict keyword on the arguments to
713 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
714 // arguments.
715 Changed |= setDoesNotThrow(F);
716 Changed |= setDoesNotCapture(F, 0);
717 Changed |= setDoesNotCapture(F, 1);
718 return Changed;
719 case LibFunc_Znwj: // new(unsigned int)
720 case LibFunc_Znwm: // new(unsigned long)
721 case LibFunc_Znaj: // new[](unsigned int)
722 case LibFunc_Znam: // new[](unsigned long)
723 case LibFunc_msvc_new_int: // new(unsigned int)
724 case LibFunc_msvc_new_longlong: // new(unsigned long long)
725 case LibFunc_msvc_new_array_int: // new[](unsigned int)
726 case LibFunc_msvc_new_array_longlong: // new[](unsigned long long)
727 // Operator new always returns a nonnull noalias pointer
728 Changed |= setRetNonNull(F);
729 Changed |= setRetDoesNotAlias(F);
730 return Changed;
731 // TODO: add LibFunc entries for:
732 // case LibFunc_memset_pattern4:
733 // case LibFunc_memset_pattern8:
734 case LibFunc_memset_pattern16:
735 Changed |= setOnlyAccessesArgMemory(F);
736 Changed |= setDoesNotCapture(F, 0);
737 Changed |= setDoesNotCapture(F, 1);
738 Changed |= setOnlyReadsMemory(F, 1);
739 return Changed;
740 // int __nvvm_reflect(const char *)
741 case LibFunc_nvvm_reflect:
742 Changed |= setDoesNotAccessMemory(F);
743 Changed |= setDoesNotThrow(F);
744 return Changed;
745
746 default:
747 // FIXME: It'd be really nice to cover all the library functions we're
748 // aware of here.
749 return false;
750 }
751 }
752
hasUnaryFloatFn(const TargetLibraryInfo * TLI,Type * Ty,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn)753 bool llvm::hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
754 LibFunc DoubleFn, LibFunc FloatFn,
755 LibFunc LongDoubleFn) {
756 switch (Ty->getTypeID()) {
757 case Type::HalfTyID:
758 return false;
759 case Type::FloatTyID:
760 return TLI->has(FloatFn);
761 case Type::DoubleTyID:
762 return TLI->has(DoubleFn);
763 default:
764 return TLI->has(LongDoubleFn);
765 }
766 }
767
getUnaryFloatFn(const TargetLibraryInfo * TLI,Type * Ty,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn)768 StringRef llvm::getUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty,
769 LibFunc DoubleFn, LibFunc FloatFn,
770 LibFunc LongDoubleFn) {
771 assert(hasUnaryFloatFn(TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&
772 "Cannot get name for unavailable function!");
773
774 switch (Ty->getTypeID()) {
775 case Type::HalfTyID:
776 llvm_unreachable("No name for HalfTy!");
777 case Type::FloatTyID:
778 return TLI->getName(FloatFn);
779 case Type::DoubleTyID:
780 return TLI->getName(DoubleFn);
781 default:
782 return TLI->getName(LongDoubleFn);
783 }
784 }
785
786 //- Emit LibCalls ------------------------------------------------------------//
787
castToCStr(Value * V,IRBuilder<> & B)788 Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
789 unsigned AS = V->getType()->getPointerAddressSpace();
790 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
791 }
792
emitStrLen(Value * Ptr,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)793 Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
794 const TargetLibraryInfo *TLI) {
795 if (!TLI->has(LibFunc_strlen))
796 return nullptr;
797
798 Module *M = B.GetInsertBlock()->getModule();
799 StringRef StrlenName = TLI->getName(LibFunc_strlen);
800 LLVMContext &Context = B.GetInsertBlock()->getContext();
801 Constant *StrLen = M->getOrInsertFunction(StrlenName, DL.getIntPtrType(Context),
802 B.getInt8PtrTy());
803 inferLibFuncAttributes(M, StrlenName, *TLI);
804 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), StrlenName);
805 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
806 CI->setCallingConv(F->getCallingConv());
807
808 return CI;
809 }
810
emitStrChr(Value * Ptr,char C,IRBuilder<> & B,const TargetLibraryInfo * TLI)811 Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
812 const TargetLibraryInfo *TLI) {
813 if (!TLI->has(LibFunc_strchr))
814 return nullptr;
815
816 Module *M = B.GetInsertBlock()->getModule();
817 StringRef StrChrName = TLI->getName(LibFunc_strchr);
818 Type *I8Ptr = B.getInt8PtrTy();
819 Type *I32Ty = B.getInt32Ty();
820 Constant *StrChr =
821 M->getOrInsertFunction(StrChrName, I8Ptr, I8Ptr, I32Ty);
822 inferLibFuncAttributes(M, StrChrName, *TLI);
823 CallInst *CI = B.CreateCall(
824 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, StrChrName);
825 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
826 CI->setCallingConv(F->getCallingConv());
827 return CI;
828 }
829
emitStrNCmp(Value * Ptr1,Value * Ptr2,Value * Len,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)830 Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
831 const DataLayout &DL, const TargetLibraryInfo *TLI) {
832 if (!TLI->has(LibFunc_strncmp))
833 return nullptr;
834
835 Module *M = B.GetInsertBlock()->getModule();
836 StringRef StrNCmpName = TLI->getName(LibFunc_strncmp);
837 LLVMContext &Context = B.GetInsertBlock()->getContext();
838 Value *StrNCmp = M->getOrInsertFunction(StrNCmpName, B.getInt32Ty(),
839 B.getInt8PtrTy(), B.getInt8PtrTy(),
840 DL.getIntPtrType(Context));
841 inferLibFuncAttributes(M, StrNCmpName, *TLI);
842 CallInst *CI = B.CreateCall(
843 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, StrNCmpName);
844
845 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
846 CI->setCallingConv(F->getCallingConv());
847
848 return CI;
849 }
850
emitStrCpy(Value * Dst,Value * Src,IRBuilder<> & B,const TargetLibraryInfo * TLI,StringRef Name)851 Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
852 const TargetLibraryInfo *TLI, StringRef Name) {
853 if (!TLI->has(LibFunc_strcpy))
854 return nullptr;
855
856 Module *M = B.GetInsertBlock()->getModule();
857 Type *I8Ptr = B.getInt8PtrTy();
858 Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr);
859 inferLibFuncAttributes(M, Name, *TLI);
860 CallInst *CI =
861 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
862 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
863 CI->setCallingConv(F->getCallingConv());
864 return CI;
865 }
866
emitStrNCpy(Value * Dst,Value * Src,Value * Len,IRBuilder<> & B,const TargetLibraryInfo * TLI,StringRef Name)867 Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
868 const TargetLibraryInfo *TLI, StringRef Name) {
869 if (!TLI->has(LibFunc_strncpy))
870 return nullptr;
871
872 Module *M = B.GetInsertBlock()->getModule();
873 Type *I8Ptr = B.getInt8PtrTy();
874 Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
875 Len->getType());
876 inferLibFuncAttributes(M, Name, *TLI);
877 CallInst *CI = B.CreateCall(
878 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, Name);
879 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
880 CI->setCallingConv(F->getCallingConv());
881 return CI;
882 }
883
emitMemCpyChk(Value * Dst,Value * Src,Value * Len,Value * ObjSize,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)884 Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
885 IRBuilder<> &B, const DataLayout &DL,
886 const TargetLibraryInfo *TLI) {
887 if (!TLI->has(LibFunc_memcpy_chk))
888 return nullptr;
889
890 Module *M = B.GetInsertBlock()->getModule();
891 AttributeList AS;
892 AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,
893 Attribute::NoUnwind);
894 LLVMContext &Context = B.GetInsertBlock()->getContext();
895 Value *MemCpy = M->getOrInsertFunction(
896 "__memcpy_chk", AttributeList::get(M->getContext(), AS), B.getInt8PtrTy(),
897 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
898 DL.getIntPtrType(Context));
899 Dst = castToCStr(Dst, B);
900 Src = castToCStr(Src, B);
901 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
902 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
903 CI->setCallingConv(F->getCallingConv());
904 return CI;
905 }
906
emitMemChr(Value * Ptr,Value * Val,Value * Len,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)907 Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
908 const DataLayout &DL, const TargetLibraryInfo *TLI) {
909 if (!TLI->has(LibFunc_memchr))
910 return nullptr;
911
912 Module *M = B.GetInsertBlock()->getModule();
913 StringRef MemChrName = TLI->getName(LibFunc_memchr);
914 LLVMContext &Context = B.GetInsertBlock()->getContext();
915 Value *MemChr = M->getOrInsertFunction(MemChrName, B.getInt8PtrTy(),
916 B.getInt8PtrTy(), B.getInt32Ty(),
917 DL.getIntPtrType(Context));
918 inferLibFuncAttributes(M, MemChrName, *TLI);
919 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, MemChrName);
920
921 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
922 CI->setCallingConv(F->getCallingConv());
923
924 return CI;
925 }
926
emitMemCmp(Value * Ptr1,Value * Ptr2,Value * Len,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)927 Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
928 const DataLayout &DL, const TargetLibraryInfo *TLI) {
929 if (!TLI->has(LibFunc_memcmp))
930 return nullptr;
931
932 Module *M = B.GetInsertBlock()->getModule();
933 StringRef MemCmpName = TLI->getName(LibFunc_memcmp);
934 LLVMContext &Context = B.GetInsertBlock()->getContext();
935 Value *MemCmp = M->getOrInsertFunction(MemCmpName, B.getInt32Ty(),
936 B.getInt8PtrTy(), B.getInt8PtrTy(),
937 DL.getIntPtrType(Context));
938 inferLibFuncAttributes(M, MemCmpName, *TLI);
939 CallInst *CI = B.CreateCall(
940 MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, MemCmpName);
941
942 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
943 CI->setCallingConv(F->getCallingConv());
944
945 return CI;
946 }
947
948 /// Append a suffix to the function name according to the type of 'Op'.
appendTypeSuffix(Value * Op,StringRef & Name,SmallString<20> & NameBuffer)949 static void appendTypeSuffix(Value *Op, StringRef &Name,
950 SmallString<20> &NameBuffer) {
951 if (!Op->getType()->isDoubleTy()) {
952 NameBuffer += Name;
953
954 if (Op->getType()->isFloatTy())
955 NameBuffer += 'f';
956 else
957 NameBuffer += 'l';
958
959 Name = NameBuffer;
960 }
961 }
962
emitUnaryFloatFnCallHelper(Value * Op,StringRef Name,IRBuilder<> & B,const AttributeList & Attrs)963 static Value *emitUnaryFloatFnCallHelper(Value *Op, StringRef Name,
964 IRBuilder<> &B,
965 const AttributeList &Attrs) {
966 assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");
967
968 Module *M = B.GetInsertBlock()->getModule();
969 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
970 Op->getType());
971 CallInst *CI = B.CreateCall(Callee, Op, Name);
972
973 // The incoming attribute set may have come from a speculatable intrinsic, but
974 // is being replaced with a library call which is not allowed to be
975 // speculatable.
976 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
977 AttributeList::FunctionIndex,
978 Attribute::Speculatable));
979 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
980 CI->setCallingConv(F->getCallingConv());
981
982 return CI;
983 }
984
emitUnaryFloatFnCall(Value * Op,StringRef Name,IRBuilder<> & B,const AttributeList & Attrs)985 Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
986 const AttributeList &Attrs) {
987 SmallString<20> NameBuffer;
988 appendTypeSuffix(Op, Name, NameBuffer);
989
990 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
991 }
992
emitUnaryFloatFnCall(Value * Op,const TargetLibraryInfo * TLI,LibFunc DoubleFn,LibFunc FloatFn,LibFunc LongDoubleFn,IRBuilder<> & B,const AttributeList & Attrs)993 Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
994 LibFunc DoubleFn, LibFunc FloatFn,
995 LibFunc LongDoubleFn, IRBuilder<> &B,
996 const AttributeList &Attrs) {
997 // Get the name of the function according to TLI.
998 StringRef Name = getUnaryFloatFn(TLI, Op->getType(),
999 DoubleFn, FloatFn, LongDoubleFn);
1000
1001 return emitUnaryFloatFnCallHelper(Op, Name, B, Attrs);
1002 }
1003
emitBinaryFloatFnCall(Value * Op1,Value * Op2,StringRef Name,IRBuilder<> & B,const AttributeList & Attrs)1004 Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
1005 IRBuilder<> &B, const AttributeList &Attrs) {
1006 assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");
1007
1008 SmallString<20> NameBuffer;
1009 appendTypeSuffix(Op1, Name, NameBuffer);
1010
1011 Module *M = B.GetInsertBlock()->getModule();
1012 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
1013 Op2->getType());
1014 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
1015 CI->setAttributes(Attrs);
1016 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
1017 CI->setCallingConv(F->getCallingConv());
1018
1019 return CI;
1020 }
1021
emitPutChar(Value * Char,IRBuilder<> & B,const TargetLibraryInfo * TLI)1022 Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
1023 const TargetLibraryInfo *TLI) {
1024 if (!TLI->has(LibFunc_putchar))
1025 return nullptr;
1026
1027 Module *M = B.GetInsertBlock()->getModule();
1028 StringRef PutCharName = TLI->getName(LibFunc_putchar);
1029 Value *PutChar = M->getOrInsertFunction(PutCharName, B.getInt32Ty(), B.getInt32Ty());
1030 inferLibFuncAttributes(M, PutCharName, *TLI);
1031 CallInst *CI = B.CreateCall(PutChar,
1032 B.CreateIntCast(Char,
1033 B.getInt32Ty(),
1034 /*isSigned*/true,
1035 "chari"),
1036 PutCharName);
1037
1038 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
1039 CI->setCallingConv(F->getCallingConv());
1040 return CI;
1041 }
1042
emitPutS(Value * Str,IRBuilder<> & B,const TargetLibraryInfo * TLI)1043 Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
1044 const TargetLibraryInfo *TLI) {
1045 if (!TLI->has(LibFunc_puts))
1046 return nullptr;
1047
1048 Module *M = B.GetInsertBlock()->getModule();
1049 StringRef PutsName = TLI->getName(LibFunc_puts);
1050 Value *PutS =
1051 M->getOrInsertFunction(PutsName, B.getInt32Ty(), B.getInt8PtrTy());
1052 inferLibFuncAttributes(M, PutsName, *TLI);
1053 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), PutsName);
1054 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
1055 CI->setCallingConv(F->getCallingConv());
1056 return CI;
1057 }
1058
emitFPutC(Value * Char,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)1059 Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
1060 const TargetLibraryInfo *TLI) {
1061 if (!TLI->has(LibFunc_fputc))
1062 return nullptr;
1063
1064 Module *M = B.GetInsertBlock()->getModule();
1065 StringRef FPutcName = TLI->getName(LibFunc_fputc);
1066 Constant *F = M->getOrInsertFunction(FPutcName, B.getInt32Ty(), B.getInt32Ty(),
1067 File->getType());
1068 if (File->getType()->isPointerTy())
1069 inferLibFuncAttributes(M, FPutcName, *TLI);
1070 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
1071 "chari");
1072 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);
1073
1074 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1075 CI->setCallingConv(Fn->getCallingConv());
1076 return CI;
1077 }
1078
emitFPutCUnlocked(Value * Char,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)1079 Value *llvm::emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
1080 const TargetLibraryInfo *TLI) {
1081 if (!TLI->has(LibFunc_fputc_unlocked))
1082 return nullptr;
1083
1084 Module *M = B.GetInsertBlock()->getModule();
1085 StringRef FPutcUnlockedName = TLI->getName(LibFunc_fputc_unlocked);
1086 Constant *F = M->getOrInsertFunction(FPutcUnlockedName, B.getInt32Ty(),
1087 B.getInt32Ty(), File->getType());
1088 if (File->getType()->isPointerTy())
1089 inferLibFuncAttributes(M, FPutcUnlockedName, *TLI);
1090 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/ true, "chari");
1091 CallInst *CI = B.CreateCall(F, {Char, File}, FPutcUnlockedName);
1092
1093 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1094 CI->setCallingConv(Fn->getCallingConv());
1095 return CI;
1096 }
1097
emitFPutS(Value * Str,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)1098 Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
1099 const TargetLibraryInfo *TLI) {
1100 if (!TLI->has(LibFunc_fputs))
1101 return nullptr;
1102
1103 Module *M = B.GetInsertBlock()->getModule();
1104 StringRef FPutsName = TLI->getName(LibFunc_fputs);
1105 Constant *F = M->getOrInsertFunction(
1106 FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType());
1107 if (File->getType()->isPointerTy())
1108 inferLibFuncAttributes(M, FPutsName, *TLI);
1109 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsName);
1110
1111 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1112 CI->setCallingConv(Fn->getCallingConv());
1113 return CI;
1114 }
1115
emitFPutSUnlocked(Value * Str,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)1116 Value *llvm::emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
1117 const TargetLibraryInfo *TLI) {
1118 if (!TLI->has(LibFunc_fputs_unlocked))
1119 return nullptr;
1120
1121 Module *M = B.GetInsertBlock()->getModule();
1122 StringRef FPutsUnlockedName = TLI->getName(LibFunc_fputs_unlocked);
1123 Constant *F = M->getOrInsertFunction(FPutsUnlockedName, B.getInt32Ty(),
1124 B.getInt8PtrTy(), File->getType());
1125 if (File->getType()->isPointerTy())
1126 inferLibFuncAttributes(M, FPutsUnlockedName, *TLI);
1127 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, FPutsUnlockedName);
1128
1129 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1130 CI->setCallingConv(Fn->getCallingConv());
1131 return CI;
1132 }
1133
emitFWrite(Value * Ptr,Value * Size,Value * File,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)1134 Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
1135 const DataLayout &DL, const TargetLibraryInfo *TLI) {
1136 if (!TLI->has(LibFunc_fwrite))
1137 return nullptr;
1138
1139 Module *M = B.GetInsertBlock()->getModule();
1140 LLVMContext &Context = B.GetInsertBlock()->getContext();
1141 StringRef FWriteName = TLI->getName(LibFunc_fwrite);
1142 Constant *F = M->getOrInsertFunction(
1143 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1144 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1145
1146 if (File->getType()->isPointerTy())
1147 inferLibFuncAttributes(M, FWriteName, *TLI);
1148 CallInst *CI =
1149 B.CreateCall(F, {castToCStr(Ptr, B), Size,
1150 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
1151
1152 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1153 CI->setCallingConv(Fn->getCallingConv());
1154 return CI;
1155 }
1156
emitMalloc(Value * Num,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)1157 Value *llvm::emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
1158 const TargetLibraryInfo *TLI) {
1159 if (!TLI->has(LibFunc_malloc))
1160 return nullptr;
1161
1162 Module *M = B.GetInsertBlock()->getModule();
1163 StringRef MallocName = TLI->getName(LibFunc_malloc);
1164 LLVMContext &Context = B.GetInsertBlock()->getContext();
1165 Value *Malloc = M->getOrInsertFunction(MallocName, B.getInt8PtrTy(),
1166 DL.getIntPtrType(Context));
1167 inferLibFuncAttributes(M, MallocName, *TLI);
1168 CallInst *CI = B.CreateCall(Malloc, Num, MallocName);
1169
1170 if (const Function *F = dyn_cast<Function>(Malloc->stripPointerCasts()))
1171 CI->setCallingConv(F->getCallingConv());
1172
1173 return CI;
1174 }
1175
emitCalloc(Value * Num,Value * Size,const AttributeList & Attrs,IRBuilder<> & B,const TargetLibraryInfo & TLI)1176 Value *llvm::emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
1177 IRBuilder<> &B, const TargetLibraryInfo &TLI) {
1178 if (!TLI.has(LibFunc_calloc))
1179 return nullptr;
1180
1181 Module *M = B.GetInsertBlock()->getModule();
1182 StringRef CallocName = TLI.getName(LibFunc_calloc);
1183 const DataLayout &DL = M->getDataLayout();
1184 IntegerType *PtrType = DL.getIntPtrType((B.GetInsertBlock()->getContext()));
1185 Value *Calloc = M->getOrInsertFunction(CallocName, Attrs, B.getInt8PtrTy(),
1186 PtrType, PtrType);
1187 inferLibFuncAttributes(M, CallocName, TLI);
1188 CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);
1189
1190 if (const auto *F = dyn_cast<Function>(Calloc->stripPointerCasts()))
1191 CI->setCallingConv(F->getCallingConv());
1192
1193 return CI;
1194 }
1195
emitFWriteUnlocked(Value * Ptr,Value * Size,Value * N,Value * File,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)1196 Value *llvm::emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1197 IRBuilder<> &B, const DataLayout &DL,
1198 const TargetLibraryInfo *TLI) {
1199 if (!TLI->has(LibFunc_fwrite_unlocked))
1200 return nullptr;
1201
1202 Module *M = B.GetInsertBlock()->getModule();
1203 LLVMContext &Context = B.GetInsertBlock()->getContext();
1204 StringRef FWriteUnlockedName = TLI->getName(LibFunc_fwrite_unlocked);
1205 Constant *F = M->getOrInsertFunction(
1206 FWriteUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1207 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1208
1209 if (File->getType()->isPointerTy())
1210 inferLibFuncAttributes(M, FWriteUnlockedName, *TLI);
1211 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1212
1213 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1214 CI->setCallingConv(Fn->getCallingConv());
1215 return CI;
1216 }
1217
emitFGetCUnlocked(Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)1218 Value *llvm::emitFGetCUnlocked(Value *File, IRBuilder<> &B,
1219 const TargetLibraryInfo *TLI) {
1220 if (!TLI->has(LibFunc_fgetc_unlocked))
1221 return nullptr;
1222
1223 Module *M = B.GetInsertBlock()->getModule();
1224 StringRef FGetCUnlockedName = TLI->getName(LibFunc_fgetc_unlocked);
1225 Constant *F =
1226 M->getOrInsertFunction(FGetCUnlockedName, B.getInt32Ty(), File->getType());
1227 if (File->getType()->isPointerTy())
1228 inferLibFuncAttributes(M, FGetCUnlockedName, *TLI);
1229 CallInst *CI = B.CreateCall(F, File, FGetCUnlockedName);
1230
1231 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1232 CI->setCallingConv(Fn->getCallingConv());
1233 return CI;
1234 }
1235
emitFGetSUnlocked(Value * Str,Value * Size,Value * File,IRBuilder<> & B,const TargetLibraryInfo * TLI)1236 Value *llvm::emitFGetSUnlocked(Value *Str, Value *Size, Value *File,
1237 IRBuilder<> &B, const TargetLibraryInfo *TLI) {
1238 if (!TLI->has(LibFunc_fgets_unlocked))
1239 return nullptr;
1240
1241 Module *M = B.GetInsertBlock()->getModule();
1242 StringRef FGetSUnlockedName = TLI->getName(LibFunc_fgets_unlocked);
1243 Constant *F =
1244 M->getOrInsertFunction(FGetSUnlockedName, B.getInt8PtrTy(),
1245 B.getInt8PtrTy(), B.getInt32Ty(), File->getType());
1246 inferLibFuncAttributes(M, FGetSUnlockedName, *TLI);
1247 CallInst *CI =
1248 B.CreateCall(F, {castToCStr(Str, B), Size, File}, FGetSUnlockedName);
1249
1250 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1251 CI->setCallingConv(Fn->getCallingConv());
1252 return CI;
1253 }
1254
emitFReadUnlocked(Value * Ptr,Value * Size,Value * N,Value * File,IRBuilder<> & B,const DataLayout & DL,const TargetLibraryInfo * TLI)1255 Value *llvm::emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
1256 IRBuilder<> &B, const DataLayout &DL,
1257 const TargetLibraryInfo *TLI) {
1258 if (!TLI->has(LibFunc_fread_unlocked))
1259 return nullptr;
1260
1261 Module *M = B.GetInsertBlock()->getModule();
1262 LLVMContext &Context = B.GetInsertBlock()->getContext();
1263 StringRef FReadUnlockedName = TLI->getName(LibFunc_fread_unlocked);
1264 Constant *F = M->getOrInsertFunction(
1265 FReadUnlockedName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
1266 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType());
1267
1268 if (File->getType()->isPointerTy())
1269 inferLibFuncAttributes(M, FReadUnlockedName, *TLI);
1270 CallInst *CI = B.CreateCall(F, {castToCStr(Ptr, B), Size, N, File});
1271
1272 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1273 CI->setCallingConv(Fn->getCallingConv());
1274 return CI;
1275 }
1276