blob: f4260a9ff9804758b5d894ccd611347ec7a2f068 [file] [log] [blame]
Eric Christopher87abfc52010-03-05 22:25:30 +00001//===- 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"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "llvm/ADT/SmallString.h"
Ahmed Bougachab0624a22016-04-27 19:04:40 +000016#include "llvm/ADT/Statistic.h"
Weiming Zhao45d4cb92015-11-24 18:57:06 +000017#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000018#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"
Eric Christopher87abfc52010-03-05 22:25:30 +000026
27using namespace llvm;
28
Ahmed Bougachab0624a22016-04-27 19:04:40 +000029#define DEBUG_TYPE "build-libcalls"
30
31//- Infer Attributes ---------------------------------------------------------//
32
33STATISTIC(NumReadNone, "Number of functions inferred as readnone");
34STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
35STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
36STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
37STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
38STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
39STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
40STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
41
42static bool setDoesNotAccessMemory(Function &F) {
43 if (F.doesNotAccessMemory())
44 return false;
45 F.setDoesNotAccessMemory();
46 ++NumReadNone;
47 return true;
48}
49
50static bool setOnlyReadsMemory(Function &F) {
51 if (F.onlyReadsMemory())
52 return false;
53 F.setOnlyReadsMemory();
54 ++NumReadOnly;
55 return true;
56}
57
58static bool setOnlyAccessesArgMemory(Function &F) {
59 if (F.onlyAccessesArgMemory())
60 return false;
61 F.setOnlyAccessesArgMemory ();
62 ++NumArgMemOnly;
63 return true;
64}
65
66static bool setDoesNotThrow(Function &F) {
67 if (F.doesNotThrow())
68 return false;
69 F.setDoesNotThrow();
70 ++NumNoUnwind;
71 return true;
72}
73
74static bool setDoesNotCapture(Function &F, unsigned n) {
75 if (F.doesNotCapture(n))
76 return false;
77 F.setDoesNotCapture(n);
78 ++NumNoCapture;
79 return true;
80}
81
82static bool setOnlyReadsMemory(Function &F, unsigned n) {
83 if (F.onlyReadsMemory(n))
84 return false;
85 F.setOnlyReadsMemory(n);
86 ++NumReadOnlyArg;
87 return true;
88}
89
90static bool setDoesNotAlias(Function &F, unsigned n) {
91 if (F.doesNotAlias(n))
92 return false;
93 F.setDoesNotAlias(n);
94 ++NumNoAlias;
95 return true;
96}
97
98static bool setNonNull(Function &F, unsigned n) {
99 assert((n != AttributeSet::ReturnIndex ||
100 F.getReturnType()->isPointerTy()) &&
101 "nonnull applies only to pointers");
102 if (F.getAttributes().hasAttribute(n, Attribute::NonNull))
103 return false;
104 F.addAttribute(n, Attribute::NonNull);
105 ++NumNonNull;
106 return true;
107}
108
109bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
110 LibFunc::Func TheLibFunc;
111 if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))
112 return false;
113
114 bool Changed = false;
115 switch (TheLibFunc) {
116 case LibFunc::strlen:
117 Changed |= setOnlyReadsMemory(F);
118 Changed |= setDoesNotThrow(F);
119 Changed |= setDoesNotCapture(F, 1);
120 return Changed;
121 case LibFunc::strchr:
122 case LibFunc::strrchr:
123 Changed |= setOnlyReadsMemory(F);
124 Changed |= setDoesNotThrow(F);
125 return Changed;
126 case LibFunc::strtol:
127 case LibFunc::strtod:
128 case LibFunc::strtof:
129 case LibFunc::strtoul:
130 case LibFunc::strtoll:
131 case LibFunc::strtold:
132 case LibFunc::strtoull:
133 Changed |= setDoesNotThrow(F);
134 Changed |= setDoesNotCapture(F, 2);
135 Changed |= setOnlyReadsMemory(F, 1);
136 return Changed;
137 case LibFunc::strcpy:
138 case LibFunc::stpcpy:
139 case LibFunc::strcat:
140 case LibFunc::strncat:
141 case LibFunc::strncpy:
142 case LibFunc::stpncpy:
143 Changed |= setDoesNotThrow(F);
144 Changed |= setDoesNotCapture(F, 2);
145 Changed |= setOnlyReadsMemory(F, 2);
146 return Changed;
147 case LibFunc::strxfrm:
148 Changed |= setDoesNotThrow(F);
149 Changed |= setDoesNotCapture(F, 1);
150 Changed |= setDoesNotCapture(F, 2);
151 Changed |= setOnlyReadsMemory(F, 2);
152 return Changed;
153 case LibFunc::strcmp: // 0,1
154 case LibFunc::strspn: // 0,1
155 case LibFunc::strncmp: // 0,1
156 case LibFunc::strcspn: // 0,1
157 case LibFunc::strcoll: // 0,1
158 case LibFunc::strcasecmp: // 0,1
159 case LibFunc::strncasecmp: //
160 Changed |= setOnlyReadsMemory(F);
161 Changed |= setDoesNotThrow(F);
162 Changed |= setDoesNotCapture(F, 1);
163 Changed |= setDoesNotCapture(F, 2);
164 return Changed;
165 case LibFunc::strstr:
166 case LibFunc::strpbrk:
167 Changed |= setOnlyReadsMemory(F);
168 Changed |= setDoesNotThrow(F);
169 Changed |= setDoesNotCapture(F, 2);
170 return Changed;
171 case LibFunc::strtok:
172 case LibFunc::strtok_r:
173 Changed |= setDoesNotThrow(F);
174 Changed |= setDoesNotCapture(F, 2);
175 Changed |= setOnlyReadsMemory(F, 2);
176 return Changed;
177 case LibFunc::scanf:
178 Changed |= setDoesNotThrow(F);
179 Changed |= setDoesNotCapture(F, 1);
180 Changed |= setOnlyReadsMemory(F, 1);
181 return Changed;
182 case LibFunc::setbuf:
183 case LibFunc::setvbuf:
184 Changed |= setDoesNotThrow(F);
185 Changed |= setDoesNotCapture(F, 1);
186 return Changed;
187 case LibFunc::strdup:
188 case LibFunc::strndup:
189 Changed |= setDoesNotThrow(F);
190 Changed |= setDoesNotAlias(F, 0);
191 Changed |= setDoesNotCapture(F, 1);
192 Changed |= setOnlyReadsMemory(F, 1);
193 return Changed;
194 case LibFunc::stat:
195 case LibFunc::statvfs:
196 Changed |= setDoesNotThrow(F);
197 Changed |= setDoesNotCapture(F, 1);
198 Changed |= setDoesNotCapture(F, 2);
199 Changed |= setOnlyReadsMemory(F, 1);
200 return Changed;
201 case LibFunc::sscanf:
202 Changed |= setDoesNotThrow(F);
203 Changed |= setDoesNotCapture(F, 1);
204 Changed |= setDoesNotCapture(F, 2);
205 Changed |= setOnlyReadsMemory(F, 1);
206 Changed |= setOnlyReadsMemory(F, 2);
207 return Changed;
208 case LibFunc::sprintf:
209 Changed |= setDoesNotThrow(F);
210 Changed |= setDoesNotCapture(F, 1);
211 Changed |= setDoesNotCapture(F, 2);
212 Changed |= setOnlyReadsMemory(F, 2);
213 return Changed;
214 case LibFunc::snprintf:
215 Changed |= setDoesNotThrow(F);
216 Changed |= setDoesNotCapture(F, 1);
217 Changed |= setDoesNotCapture(F, 3);
218 Changed |= setOnlyReadsMemory(F, 3);
219 return Changed;
220 case LibFunc::setitimer:
221 Changed |= setDoesNotThrow(F);
222 Changed |= setDoesNotCapture(F, 2);
223 Changed |= setDoesNotCapture(F, 3);
224 Changed |= setOnlyReadsMemory(F, 2);
225 return Changed;
226 case LibFunc::system:
227 // May throw; "system" is a valid pthread cancellation point.
228 Changed |= setDoesNotCapture(F, 1);
229 Changed |= setOnlyReadsMemory(F, 1);
230 return Changed;
231 case LibFunc::malloc:
232 Changed |= setDoesNotThrow(F);
233 Changed |= setDoesNotAlias(F, 0);
234 return Changed;
235 case LibFunc::memcmp:
236 Changed |= setOnlyReadsMemory(F);
237 Changed |= setDoesNotThrow(F);
238 Changed |= setDoesNotCapture(F, 1);
239 Changed |= setDoesNotCapture(F, 2);
240 return Changed;
241 case LibFunc::memchr:
242 case LibFunc::memrchr:
243 Changed |= setOnlyReadsMemory(F);
244 Changed |= setDoesNotThrow(F);
245 return Changed;
246 case LibFunc::modf:
247 case LibFunc::modff:
248 case LibFunc::modfl:
249 Changed |= setDoesNotThrow(F);
250 Changed |= setDoesNotCapture(F, 2);
251 return Changed;
252 case LibFunc::memcpy:
253 case LibFunc::memccpy:
254 case LibFunc::memmove:
255 Changed |= setDoesNotThrow(F);
256 Changed |= setDoesNotCapture(F, 2);
257 Changed |= setOnlyReadsMemory(F, 2);
258 return Changed;
259 case LibFunc::memcpy_chk:
260 Changed |= setDoesNotThrow(F);
261 return Changed;
262 case LibFunc::memalign:
263 Changed |= setDoesNotAlias(F, 0);
264 return Changed;
265 case LibFunc::mkdir:
266 Changed |= setDoesNotThrow(F);
267 Changed |= setDoesNotCapture(F, 1);
268 Changed |= setOnlyReadsMemory(F, 1);
269 return Changed;
270 case LibFunc::mktime:
271 Changed |= setDoesNotThrow(F);
272 Changed |= setDoesNotCapture(F, 1);
273 return Changed;
274 case LibFunc::realloc:
275 Changed |= setDoesNotThrow(F);
276 Changed |= setDoesNotAlias(F, 0);
277 Changed |= setDoesNotCapture(F, 1);
278 return Changed;
279 case LibFunc::read:
280 // May throw; "read" is a valid pthread cancellation point.
281 Changed |= setDoesNotCapture(F, 2);
282 return Changed;
283 case LibFunc::rewind:
284 Changed |= setDoesNotThrow(F);
285 Changed |= setDoesNotCapture(F, 1);
286 return Changed;
287 case LibFunc::rmdir:
288 case LibFunc::remove:
289 case LibFunc::realpath:
290 Changed |= setDoesNotThrow(F);
291 Changed |= setDoesNotCapture(F, 1);
292 Changed |= setOnlyReadsMemory(F, 1);
293 return Changed;
294 case LibFunc::rename:
295 Changed |= setDoesNotThrow(F);
296 Changed |= setDoesNotCapture(F, 1);
297 Changed |= setDoesNotCapture(F, 2);
298 Changed |= setOnlyReadsMemory(F, 1);
299 Changed |= setOnlyReadsMemory(F, 2);
300 return Changed;
301 case LibFunc::readlink:
302 Changed |= setDoesNotThrow(F);
303 Changed |= setDoesNotCapture(F, 1);
304 Changed |= setDoesNotCapture(F, 2);
305 Changed |= setOnlyReadsMemory(F, 1);
306 return Changed;
307 case LibFunc::write:
308 // May throw; "write" is a valid pthread cancellation point.
309 Changed |= setDoesNotCapture(F, 2);
310 Changed |= setOnlyReadsMemory(F, 2);
311 return Changed;
312 case LibFunc::bcopy:
313 Changed |= setDoesNotThrow(F);
314 Changed |= setDoesNotCapture(F, 1);
315 Changed |= setDoesNotCapture(F, 2);
316 Changed |= setOnlyReadsMemory(F, 1);
317 return Changed;
318 case LibFunc::bcmp:
319 Changed |= setDoesNotThrow(F);
320 Changed |= setOnlyReadsMemory(F);
321 Changed |= setDoesNotCapture(F, 1);
322 Changed |= setDoesNotCapture(F, 2);
323 return Changed;
324 case LibFunc::bzero:
325 Changed |= setDoesNotThrow(F);
326 Changed |= setDoesNotCapture(F, 1);
327 return Changed;
328 case LibFunc::calloc:
329 Changed |= setDoesNotThrow(F);
330 Changed |= setDoesNotAlias(F, 0);
331 return Changed;
332 case LibFunc::chmod:
333 case LibFunc::chown:
334 Changed |= setDoesNotThrow(F);
335 Changed |= setDoesNotCapture(F, 1);
336 Changed |= setOnlyReadsMemory(F, 1);
337 return Changed;
338 case LibFunc::ctermid:
339 case LibFunc::clearerr:
340 case LibFunc::closedir:
341 Changed |= setDoesNotThrow(F);
342 Changed |= setDoesNotCapture(F, 1);
343 return Changed;
344 case LibFunc::atoi:
345 case LibFunc::atol:
346 case LibFunc::atof:
347 case LibFunc::atoll:
348 Changed |= setDoesNotThrow(F);
349 Changed |= setOnlyReadsMemory(F);
350 Changed |= setDoesNotCapture(F, 1);
351 return Changed;
352 case LibFunc::access:
353 Changed |= setDoesNotThrow(F);
354 Changed |= setDoesNotCapture(F, 1);
355 Changed |= setOnlyReadsMemory(F, 1);
356 return Changed;
357 case LibFunc::fopen:
358 Changed |= setDoesNotThrow(F);
359 Changed |= setDoesNotAlias(F, 0);
360 Changed |= setDoesNotCapture(F, 1);
361 Changed |= setDoesNotCapture(F, 2);
362 Changed |= setOnlyReadsMemory(F, 1);
363 Changed |= setOnlyReadsMemory(F, 2);
364 return Changed;
365 case LibFunc::fdopen:
366 Changed |= setDoesNotThrow(F);
367 Changed |= setDoesNotAlias(F, 0);
368 Changed |= setDoesNotCapture(F, 2);
369 Changed |= setOnlyReadsMemory(F, 2);
370 return Changed;
371 case LibFunc::feof:
372 case LibFunc::free:
373 case LibFunc::fseek:
374 case LibFunc::ftell:
375 case LibFunc::fgetc:
376 case LibFunc::fseeko:
377 case LibFunc::ftello:
378 case LibFunc::fileno:
379 case LibFunc::fflush:
380 case LibFunc::fclose:
381 case LibFunc::fsetpos:
382 case LibFunc::flockfile:
383 case LibFunc::funlockfile:
384 case LibFunc::ftrylockfile:
385 Changed |= setDoesNotThrow(F);
386 Changed |= setDoesNotCapture(F, 1);
387 return Changed;
388 case LibFunc::ferror:
389 Changed |= setDoesNotThrow(F);
390 Changed |= setDoesNotCapture(F, 1);
391 Changed |= setOnlyReadsMemory(F);
392 return Changed;
393 case LibFunc::fputc:
394 case LibFunc::fstat:
395 case LibFunc::frexp:
396 case LibFunc::frexpf:
397 case LibFunc::frexpl:
398 case LibFunc::fstatvfs:
399 Changed |= setDoesNotThrow(F);
400 Changed |= setDoesNotCapture(F, 2);
401 return Changed;
402 case LibFunc::fgets:
403 Changed |= setDoesNotThrow(F);
404 Changed |= setDoesNotCapture(F, 3);
405 return Changed;
406 case LibFunc::fread:
407 Changed |= setDoesNotThrow(F);
408 Changed |= setDoesNotCapture(F, 1);
409 Changed |= setDoesNotCapture(F, 4);
410 return Changed;
411 case LibFunc::fwrite:
412 Changed |= setDoesNotThrow(F);
413 Changed |= setDoesNotCapture(F, 1);
414 Changed |= setDoesNotCapture(F, 4);
415 // FIXME: readonly #1?
416 return Changed;
417 case LibFunc::fputs:
418 Changed |= setDoesNotThrow(F);
419 Changed |= setDoesNotCapture(F, 1);
420 Changed |= setDoesNotCapture(F, 2);
421 Changed |= setOnlyReadsMemory(F, 1);
422 return Changed;
423 case LibFunc::fscanf:
424 case LibFunc::fprintf:
425 Changed |= setDoesNotThrow(F);
426 Changed |= setDoesNotCapture(F, 1);
427 Changed |= setDoesNotCapture(F, 2);
428 Changed |= setOnlyReadsMemory(F, 2);
429 return Changed;
430 case LibFunc::fgetpos:
431 Changed |= setDoesNotThrow(F);
432 Changed |= setDoesNotCapture(F, 1);
433 Changed |= setDoesNotCapture(F, 2);
434 return Changed;
435 case LibFunc::getc:
436 case LibFunc::getlogin_r:
437 case LibFunc::getc_unlocked:
438 Changed |= setDoesNotThrow(F);
439 Changed |= setDoesNotCapture(F, 1);
440 return Changed;
441 case LibFunc::getenv:
442 Changed |= setDoesNotThrow(F);
443 Changed |= setOnlyReadsMemory(F);
444 Changed |= setDoesNotCapture(F, 1);
445 return Changed;
446 case LibFunc::gets:
447 case LibFunc::getchar:
448 Changed |= setDoesNotThrow(F);
449 return Changed;
450 case LibFunc::getitimer:
451 Changed |= setDoesNotThrow(F);
452 Changed |= setDoesNotCapture(F, 2);
453 return Changed;
454 case LibFunc::getpwnam:
455 Changed |= setDoesNotThrow(F);
456 Changed |= setDoesNotCapture(F, 1);
457 Changed |= setOnlyReadsMemory(F, 1);
458 return Changed;
459 case LibFunc::ungetc:
460 Changed |= setDoesNotThrow(F);
461 Changed |= setDoesNotCapture(F, 2);
462 return Changed;
463 case LibFunc::uname:
464 Changed |= setDoesNotThrow(F);
465 Changed |= setDoesNotCapture(F, 1);
466 return Changed;
467 case LibFunc::unlink:
468 Changed |= setDoesNotThrow(F);
469 Changed |= setDoesNotCapture(F, 1);
470 Changed |= setOnlyReadsMemory(F, 1);
471 return Changed;
472 case LibFunc::unsetenv:
473 Changed |= setDoesNotThrow(F);
474 Changed |= setDoesNotCapture(F, 1);
475 Changed |= setOnlyReadsMemory(F, 1);
476 return Changed;
477 case LibFunc::utime:
478 case LibFunc::utimes:
479 Changed |= setDoesNotThrow(F);
480 Changed |= setDoesNotCapture(F, 1);
481 Changed |= setDoesNotCapture(F, 2);
482 Changed |= setOnlyReadsMemory(F, 1);
483 Changed |= setOnlyReadsMemory(F, 2);
484 return Changed;
485 case LibFunc::putc:
486 Changed |= setDoesNotThrow(F);
487 Changed |= setDoesNotCapture(F, 2);
488 return Changed;
489 case LibFunc::puts:
490 case LibFunc::printf:
491 case LibFunc::perror:
492 Changed |= setDoesNotThrow(F);
493 Changed |= setDoesNotCapture(F, 1);
494 Changed |= setOnlyReadsMemory(F, 1);
495 return Changed;
496 case LibFunc::pread:
497 // May throw; "pread" is a valid pthread cancellation point.
498 Changed |= setDoesNotCapture(F, 2);
499 return Changed;
500 case LibFunc::pwrite:
501 // May throw; "pwrite" is a valid pthread cancellation point.
502 Changed |= setDoesNotCapture(F, 2);
503 Changed |= setOnlyReadsMemory(F, 2);
504 return Changed;
505 case LibFunc::putchar:
506 Changed |= setDoesNotThrow(F);
507 return Changed;
508 case LibFunc::popen:
509 Changed |= setDoesNotThrow(F);
510 Changed |= setDoesNotAlias(F, 0);
511 Changed |= setDoesNotCapture(F, 1);
512 Changed |= setDoesNotCapture(F, 2);
513 Changed |= setOnlyReadsMemory(F, 1);
514 Changed |= setOnlyReadsMemory(F, 2);
515 return Changed;
516 case LibFunc::pclose:
517 Changed |= setDoesNotThrow(F);
518 Changed |= setDoesNotCapture(F, 1);
519 return Changed;
520 case LibFunc::vscanf:
521 Changed |= setDoesNotThrow(F);
522 Changed |= setDoesNotCapture(F, 1);
523 Changed |= setOnlyReadsMemory(F, 1);
524 return Changed;
525 case LibFunc::vsscanf:
526 Changed |= setDoesNotThrow(F);
527 Changed |= setDoesNotCapture(F, 1);
528 Changed |= setDoesNotCapture(F, 2);
529 Changed |= setOnlyReadsMemory(F, 1);
530 Changed |= setOnlyReadsMemory(F, 2);
531 return Changed;
532 case LibFunc::vfscanf:
533 Changed |= setDoesNotThrow(F);
534 Changed |= setDoesNotCapture(F, 1);
535 Changed |= setDoesNotCapture(F, 2);
536 Changed |= setOnlyReadsMemory(F, 2);
537 return Changed;
538 case LibFunc::valloc:
539 Changed |= setDoesNotThrow(F);
540 Changed |= setDoesNotAlias(F, 0);
541 return Changed;
542 case LibFunc::vprintf:
543 Changed |= setDoesNotThrow(F);
544 Changed |= setDoesNotCapture(F, 1);
545 Changed |= setOnlyReadsMemory(F, 1);
546 return Changed;
547 case LibFunc::vfprintf:
548 case LibFunc::vsprintf:
549 Changed |= setDoesNotThrow(F);
550 Changed |= setDoesNotCapture(F, 1);
551 Changed |= setDoesNotCapture(F, 2);
552 Changed |= setOnlyReadsMemory(F, 2);
553 return Changed;
554 case LibFunc::vsnprintf:
555 Changed |= setDoesNotThrow(F);
556 Changed |= setDoesNotCapture(F, 1);
557 Changed |= setDoesNotCapture(F, 3);
558 Changed |= setOnlyReadsMemory(F, 3);
559 return Changed;
560 case LibFunc::open:
561 // May throw; "open" is a valid pthread cancellation point.
562 Changed |= setDoesNotCapture(F, 1);
563 Changed |= setOnlyReadsMemory(F, 1);
564 return Changed;
565 case LibFunc::opendir:
566 Changed |= setDoesNotThrow(F);
567 Changed |= setDoesNotAlias(F, 0);
568 Changed |= setDoesNotCapture(F, 1);
569 Changed |= setOnlyReadsMemory(F, 1);
570 return Changed;
571 case LibFunc::tmpfile:
572 Changed |= setDoesNotThrow(F);
573 Changed |= setDoesNotAlias(F, 0);
574 return Changed;
575 case LibFunc::times:
576 Changed |= setDoesNotThrow(F);
577 Changed |= setDoesNotCapture(F, 1);
578 return Changed;
579 case LibFunc::htonl:
580 case LibFunc::htons:
581 case LibFunc::ntohl:
582 case LibFunc::ntohs:
583 Changed |= setDoesNotThrow(F);
584 Changed |= setDoesNotAccessMemory(F);
585 return Changed;
586 case LibFunc::lstat:
587 Changed |= setDoesNotThrow(F);
588 Changed |= setDoesNotCapture(F, 1);
589 Changed |= setDoesNotCapture(F, 2);
590 Changed |= setOnlyReadsMemory(F, 1);
591 return Changed;
592 case LibFunc::lchown:
593 Changed |= setDoesNotThrow(F);
594 Changed |= setDoesNotCapture(F, 1);
595 Changed |= setOnlyReadsMemory(F, 1);
596 return Changed;
597 case LibFunc::qsort:
598 // May throw; places call through function pointer.
599 Changed |= setDoesNotCapture(F, 4);
600 return Changed;
601 case LibFunc::dunder_strdup:
602 case LibFunc::dunder_strndup:
603 Changed |= setDoesNotThrow(F);
604 Changed |= setDoesNotAlias(F, 0);
605 Changed |= setDoesNotCapture(F, 1);
606 Changed |= setOnlyReadsMemory(F, 1);
607 return Changed;
608 case LibFunc::dunder_strtok_r:
609 Changed |= setDoesNotThrow(F);
610 Changed |= setDoesNotCapture(F, 2);
611 Changed |= setOnlyReadsMemory(F, 2);
612 return Changed;
613 case LibFunc::under_IO_getc:
614 Changed |= setDoesNotThrow(F);
615 Changed |= setDoesNotCapture(F, 1);
616 return Changed;
617 case LibFunc::under_IO_putc:
618 Changed |= setDoesNotThrow(F);
619 Changed |= setDoesNotCapture(F, 2);
620 return Changed;
621 case LibFunc::dunder_isoc99_scanf:
622 Changed |= setDoesNotThrow(F);
623 Changed |= setDoesNotCapture(F, 1);
624 Changed |= setOnlyReadsMemory(F, 1);
625 return Changed;
626 case LibFunc::stat64:
627 case LibFunc::lstat64:
628 case LibFunc::statvfs64:
629 Changed |= setDoesNotThrow(F);
630 Changed |= setDoesNotCapture(F, 1);
631 Changed |= setDoesNotCapture(F, 2);
632 Changed |= setOnlyReadsMemory(F, 1);
633 return Changed;
634 case LibFunc::dunder_isoc99_sscanf:
635 Changed |= setDoesNotThrow(F);
636 Changed |= setDoesNotCapture(F, 1);
637 Changed |= setDoesNotCapture(F, 2);
638 Changed |= setOnlyReadsMemory(F, 1);
639 Changed |= setOnlyReadsMemory(F, 2);
640 return Changed;
641 case LibFunc::fopen64:
642 Changed |= setDoesNotThrow(F);
643 Changed |= setDoesNotAlias(F, 0);
644 Changed |= setDoesNotCapture(F, 1);
645 Changed |= setDoesNotCapture(F, 2);
646 Changed |= setOnlyReadsMemory(F, 1);
647 Changed |= setOnlyReadsMemory(F, 2);
648 return Changed;
649 case LibFunc::fseeko64:
650 case LibFunc::ftello64:
651 Changed |= setDoesNotThrow(F);
652 Changed |= setDoesNotCapture(F, 1);
653 return Changed;
654 case LibFunc::tmpfile64:
655 Changed |= setDoesNotThrow(F);
656 Changed |= setDoesNotAlias(F, 0);
657 return Changed;
658 case LibFunc::fstat64:
659 case LibFunc::fstatvfs64:
660 Changed |= setDoesNotThrow(F);
661 Changed |= setDoesNotCapture(F, 2);
662 return Changed;
663 case LibFunc::open64:
664 // May throw; "open" is a valid pthread cancellation point.
665 Changed |= setDoesNotCapture(F, 1);
666 Changed |= setOnlyReadsMemory(F, 1);
667 return Changed;
668 case LibFunc::gettimeofday:
669 // Currently some platforms have the restrict keyword on the arguments to
670 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
671 // arguments.
672 Changed |= setDoesNotThrow(F);
673 Changed |= setDoesNotCapture(F, 1);
674 Changed |= setDoesNotCapture(F, 2);
675 return Changed;
676 case LibFunc::Znwj: // new(unsigned int)
677 case LibFunc::Znwm: // new(unsigned long)
678 case LibFunc::Znaj: // new[](unsigned int)
679 case LibFunc::Znam: // new[](unsigned long)
680 case LibFunc::msvc_new_int: // new(unsigned int)
681 case LibFunc::msvc_new_longlong: // new(unsigned long long)
682 case LibFunc::msvc_new_array_int: // new[](unsigned int)
683 case LibFunc::msvc_new_array_longlong: // new[](unsigned long long)
684 // Operator new always returns a nonnull noalias pointer
685 Changed |= setNonNull(F, AttributeSet::ReturnIndex);
686 Changed |= setDoesNotAlias(F, AttributeSet::ReturnIndex);
687 return Changed;
688 //TODO: add LibFunc entries for:
689 //case LibFunc::memset_pattern4:
690 //case LibFunc::memset_pattern8:
691 case LibFunc::memset_pattern16:
692 Changed |= setOnlyAccessesArgMemory(F);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000693 Changed |= setDoesNotCapture(F, 1);
694 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000695 Changed |= setOnlyReadsMemory(F, 2);
696 return Changed;
697 // int __nvvm_reflect(const char *)
698 case LibFunc::nvvm_reflect:
699 Changed |= setDoesNotAccessMemory(F);
700 Changed |= setDoesNotThrow(F);
701 return Changed;
702
703 default:
704 // FIXME: It'd be really nice to cover all the library functions we're
705 // aware of here.
706 return false;
707 }
708}
709
710//- Emit LibCalls ------------------------------------------------------------//
711
Sanjay Pateld3112a52016-01-19 19:46:10 +0000712Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000713 unsigned AS = V->getType()->getPointerAddressSpace();
714 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000715}
716
Sanjay Pateld3112a52016-01-19 19:46:10 +0000717Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000718 const TargetLibraryInfo *TLI) {
719 if (!TLI->has(LibFunc::strlen))
Craig Topperf40110f2014-04-25 05:29:35 +0000720 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000721
Sanjay Pateld4af2972016-01-19 19:58:49 +0000722 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000723 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000724 Constant *StrLen = M->getOrInsertFunction("strlen", DL.getIntPtrType(Context),
725 B.getInt8PtrTy(), nullptr);
726 inferLibFuncAttributes(*M->getFunction("strlen"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000727 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), "strlen");
Evan Chengad6efbf2014-03-12 18:09:37 +0000728 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
729 CI->setCallingConv(F->getCallingConv());
730
Eric Christopher87abfc52010-03-05 22:25:30 +0000731 return CI;
732}
733
Sanjay Pateld3112a52016-01-19 19:46:10 +0000734Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000735 const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000736 if (!TLI->has(LibFunc::strchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000737 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000738
Sanjay Pateld4af2972016-01-19 19:58:49 +0000739 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000740 Type *I8Ptr = B.getInt8PtrTy();
741 Type *I32Ty = B.getInt32Ty();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000742 Constant *StrChr =
743 M->getOrInsertFunction("strchr", I8Ptr, I8Ptr, I32Ty, nullptr);
744 inferLibFuncAttributes(*M->getFunction("strchr"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000745 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000746 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, "strchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000747 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
748 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000749 return CI;
750}
751
Sanjay Pateld3112a52016-01-19 19:46:10 +0000752Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000753 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000754 if (!TLI->has(LibFunc::strncmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000755 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000756
Sanjay Pateld4af2972016-01-19 19:58:49 +0000757 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000758 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000759 Value *StrNCmp = M->getOrInsertFunction("strncmp", B.getInt32Ty(),
760 B.getInt8PtrTy(), B.getInt8PtrTy(),
761 DL.getIntPtrType(Context), nullptr);
762 inferLibFuncAttributes(*M->getFunction("strncmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000763 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000764 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000765
766 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
767 CI->setCallingConv(F->getCallingConv());
768
Benjamin Kramer11188602010-06-15 21:34:25 +0000769 return CI;
770}
771
Sanjay Pateld3112a52016-01-19 19:46:10 +0000772Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000773 const TargetLibraryInfo *TLI, StringRef Name) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000774 if (!TLI->has(LibFunc::strcpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000775 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000776
Sanjay Pateld4af2972016-01-19 19:58:49 +0000777 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000778 Type *I8Ptr = B.getInt8PtrTy();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000779 Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr, nullptr);
780 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000781 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +0000782 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
Evan Chengad6efbf2014-03-12 18:09:37 +0000783 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
784 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000785 return CI;
786}
787
Sanjay Pateld3112a52016-01-19 19:46:10 +0000788Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000789 const TargetLibraryInfo *TLI, StringRef Name) {
790 if (!TLI->has(LibFunc::strncpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000791 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000792
Sanjay Pateld4af2972016-01-19 19:58:49 +0000793 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000794 Type *I8Ptr = B.getInt8PtrTy();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000795 Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
Reid Kleckner971c3ea2014-11-13 22:55:19 +0000796 Len->getType(), nullptr);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000797 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000798 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000799 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy");
Evan Chengad6efbf2014-03-12 18:09:37 +0000800 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
801 CI->setCallingConv(F->getCallingConv());
Eric Christopher43dc11c2010-03-11 01:25:07 +0000802 return CI;
803}
804
Sanjay Pateld3112a52016-01-19 19:46:10 +0000805Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000806 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000807 const TargetLibraryInfo *TLI) {
808 if (!TLI->has(LibFunc::memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000809 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000810
Sanjay Pateld4af2972016-01-19 19:58:49 +0000811 Module *M = B.GetInsertBlock()->getModule();
Bill Wendling201d7b22013-01-26 00:03:11 +0000812 AttributeSet AS;
813 AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
814 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000815 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000816 Value *MemCpy = M->getOrInsertFunction(
817 "__memcpy_chk", AttributeSet::get(M->getContext(), AS), B.getInt8PtrTy(),
818 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
819 DL.getIntPtrType(Context), nullptr);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000820 Dst = castToCStr(Dst, B);
821 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000822 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
Evan Chengad6efbf2014-03-12 18:09:37 +0000823 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
824 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000825 return CI;
826}
827
Sanjay Pateld3112a52016-01-19 19:46:10 +0000828Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000829 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000830 if (!TLI->has(LibFunc::memchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000831 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000832
Sanjay Pateld4af2972016-01-19 19:58:49 +0000833 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000834 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000835 Value *MemChr = M->getOrInsertFunction("memchr", B.getInt8PtrTy(),
836 B.getInt8PtrTy(), B.getInt32Ty(),
837 DL.getIntPtrType(Context), nullptr);
838 inferLibFuncAttributes(*M->getFunction("memchr"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000839 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000840
841 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
842 CI->setCallingConv(F->getCallingConv());
843
Eric Christopher87abfc52010-03-05 22:25:30 +0000844 return CI;
845}
846
Sanjay Pateld3112a52016-01-19 19:46:10 +0000847Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000848 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000849 if (!TLI->has(LibFunc::memcmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000850 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000851
Sanjay Pateld4af2972016-01-19 19:58:49 +0000852 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000853 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000854 Value *MemCmp = M->getOrInsertFunction("memcmp", B.getInt32Ty(),
855 B.getInt8PtrTy(), B.getInt8PtrTy(),
856 DL.getIntPtrType(Context), nullptr);
857 inferLibFuncAttributes(*M->getFunction("memcmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000858 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000859 MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000860
861 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
862 CI->setCallingConv(F->getCallingConv());
863
Eric Christopher87abfc52010-03-05 22:25:30 +0000864 return CI;
865}
866
Yi Jiang6ab044e2013-12-16 22:42:40 +0000867/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +0000868static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +0000869 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000870 if (!Op->getType()->isDoubleTy()) {
871 NameBuffer += Name;
872
873 if (Op->getType()->isFloatTy())
874 NameBuffer += 'f';
875 else
876 NameBuffer += 'l';
877
878 Name = NameBuffer;
879 }
Yi Jiang6ab044e2013-12-16 22:42:40 +0000880}
881
Sanjay Pateld3112a52016-01-19 19:46:10 +0000882Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
Bill Wendlinge94d8432012-12-07 23:16:57 +0000883 const AttributeSet &Attrs) {
Benjamin Kramerb106bcc2011-11-15 19:12:09 +0000884 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000885 appendTypeSuffix(Op, Name, NameBuffer);
Eric Christopher87abfc52010-03-05 22:25:30 +0000886
Sanjay Pateld4af2972016-01-19 19:58:49 +0000887 Module *M = B.GetInsertBlock()->getModule();
Eric Christopher87abfc52010-03-05 22:25:30 +0000888 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Reid Kleckner971c3ea2014-11-13 22:55:19 +0000889 Op->getType(), nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000890 CallInst *CI = B.CreateCall(Callee, Op, Name);
891 CI->setAttributes(Attrs);
Evan Chengad6efbf2014-03-12 18:09:37 +0000892 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
893 CI->setCallingConv(F->getCallingConv());
894
Eric Christopher87abfc52010-03-05 22:25:30 +0000895 return CI;
896}
897
Sanjay Pateld3112a52016-01-19 19:46:10 +0000898Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Yi Jiang6ab044e2013-12-16 22:42:40 +0000899 IRBuilder<> &B, const AttributeSet &Attrs) {
900 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000901 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000902
Sanjay Pateld4af2972016-01-19 19:58:49 +0000903 Module *M = B.GetInsertBlock()->getModule();
Sanjay Patelb50325e2016-01-19 19:17:47 +0000904 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
905 Op2->getType(), nullptr);
David Blaikieff6409d2015-05-18 22:13:54 +0000906 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000907 CI->setAttributes(Attrs);
Evan Chengad6efbf2014-03-12 18:09:37 +0000908 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
909 CI->setCallingConv(F->getCallingConv());
910
Yi Jiang6ab044e2013-12-16 22:42:40 +0000911 return CI;
912}
913
Sanjay Pateld3112a52016-01-19 19:46:10 +0000914Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000915 const TargetLibraryInfo *TLI) {
916 if (!TLI->has(LibFunc::putchar))
Craig Topperf40110f2014-04-25 05:29:35 +0000917 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000918
Sanjay Pateld4af2972016-01-19 19:58:49 +0000919 Module *M = B.GetInsertBlock()->getModule();
Eric Christopher87abfc52010-03-05 22:25:30 +0000920 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
Reid Kleckner971c3ea2014-11-13 22:55:19 +0000921 B.getInt32Ty(), nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000922 CallInst *CI = B.CreateCall(PutChar,
923 B.CreateIntCast(Char,
924 B.getInt32Ty(),
925 /*isSigned*/true,
926 "chari"),
927 "putchar");
Evan Chengad6efbf2014-03-12 18:09:37 +0000928
929 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
930 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000931 return CI;
932}
933
Sanjay Pateld3112a52016-01-19 19:46:10 +0000934Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000935 const TargetLibraryInfo *TLI) {
936 if (!TLI->has(LibFunc::puts))
Craig Topperf40110f2014-04-25 05:29:35 +0000937 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000938
Sanjay Pateld4af2972016-01-19 19:58:49 +0000939 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000940 Value *PutS =
941 M->getOrInsertFunction("puts", B.getInt32Ty(), B.getInt8PtrTy(), nullptr);
942 inferLibFuncAttributes(*M->getFunction("puts"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000943 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts");
Evan Chengad6efbf2014-03-12 18:09:37 +0000944 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
945 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000946 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000947}
948
Sanjay Pateld3112a52016-01-19 19:46:10 +0000949Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000950 const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000951 if (!TLI->has(LibFunc::fputc))
Craig Topperf40110f2014-04-25 05:29:35 +0000952 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000953
Sanjay Pateld4af2972016-01-19 19:58:49 +0000954 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000955 Constant *F = M->getOrInsertFunction("fputc", B.getInt32Ty(), B.getInt32Ty(),
956 File->getType(), nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000957 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000958 inferLibFuncAttributes(*M->getFunction("fputc"), *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000959 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
960 "chari");
David Blaikieff6409d2015-05-18 22:13:54 +0000961 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc");
Evan Chengad6efbf2014-03-12 18:09:37 +0000962
963 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
964 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000965 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000966}
967
Sanjay Pateld3112a52016-01-19 19:46:10 +0000968Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000969 const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000970 if (!TLI->has(LibFunc::fputs))
Craig Topperf40110f2014-04-25 05:29:35 +0000971 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000972
Sanjay Pateld4af2972016-01-19 19:58:49 +0000973 Module *M = B.GetInsertBlock()->getModule();
Eli Friedman489c0ff2011-11-17 01:27:36 +0000974 StringRef FPutsName = TLI->getName(LibFunc::fputs);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000975 Constant *F = M->getOrInsertFunction(
976 FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType(), nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000977 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000978 inferLibFuncAttributes(*M->getFunction(FPutsName), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000979 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs");
Evan Chengad6efbf2014-03-12 18:09:37 +0000980
981 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
982 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000983 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000984}
985
Sanjay Pateld3112a52016-01-19 19:46:10 +0000986Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000987 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000988 if (!TLI->has(LibFunc::fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +0000989 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000990
Sanjay Pateld4af2972016-01-19 19:58:49 +0000991 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000992 LLVMContext &Context = B.GetInsertBlock()->getContext();
Eli Friedman489c0ff2011-11-17 01:27:36 +0000993 StringRef FWriteName = TLI->getName(LibFunc::fwrite);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000994 Constant *F = M->getOrInsertFunction(
995 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
996 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType(),
997 nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000998 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000999 inferLibFuncAttributes(*M->getFunction(FWriteName), *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001000 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001001 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001002 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001003
1004 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1005 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001006 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001007}