blob: e61b04fbdd574ab0fc8b299ee11cd64a3ec80ad9 [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:
Andrew Kaylorb99d1cc2016-07-29 18:23:18 +0000253 case LibFunc::mempcpy:
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000254 case LibFunc::memccpy:
255 case LibFunc::memmove:
256 Changed |= setDoesNotThrow(F);
257 Changed |= setDoesNotCapture(F, 2);
258 Changed |= setOnlyReadsMemory(F, 2);
259 return Changed;
260 case LibFunc::memcpy_chk:
261 Changed |= setDoesNotThrow(F);
262 return Changed;
263 case LibFunc::memalign:
264 Changed |= setDoesNotAlias(F, 0);
265 return Changed;
266 case LibFunc::mkdir:
267 Changed |= setDoesNotThrow(F);
268 Changed |= setDoesNotCapture(F, 1);
269 Changed |= setOnlyReadsMemory(F, 1);
270 return Changed;
271 case LibFunc::mktime:
272 Changed |= setDoesNotThrow(F);
273 Changed |= setDoesNotCapture(F, 1);
274 return Changed;
275 case LibFunc::realloc:
276 Changed |= setDoesNotThrow(F);
277 Changed |= setDoesNotAlias(F, 0);
278 Changed |= setDoesNotCapture(F, 1);
279 return Changed;
280 case LibFunc::read:
281 // May throw; "read" is a valid pthread cancellation point.
282 Changed |= setDoesNotCapture(F, 2);
283 return Changed;
284 case LibFunc::rewind:
285 Changed |= setDoesNotThrow(F);
286 Changed |= setDoesNotCapture(F, 1);
287 return Changed;
288 case LibFunc::rmdir:
289 case LibFunc::remove:
290 case LibFunc::realpath:
291 Changed |= setDoesNotThrow(F);
292 Changed |= setDoesNotCapture(F, 1);
293 Changed |= setOnlyReadsMemory(F, 1);
294 return Changed;
295 case LibFunc::rename:
296 Changed |= setDoesNotThrow(F);
297 Changed |= setDoesNotCapture(F, 1);
298 Changed |= setDoesNotCapture(F, 2);
299 Changed |= setOnlyReadsMemory(F, 1);
300 Changed |= setOnlyReadsMemory(F, 2);
301 return Changed;
302 case LibFunc::readlink:
303 Changed |= setDoesNotThrow(F);
304 Changed |= setDoesNotCapture(F, 1);
305 Changed |= setDoesNotCapture(F, 2);
306 Changed |= setOnlyReadsMemory(F, 1);
307 return Changed;
308 case LibFunc::write:
309 // May throw; "write" is a valid pthread cancellation point.
310 Changed |= setDoesNotCapture(F, 2);
311 Changed |= setOnlyReadsMemory(F, 2);
312 return Changed;
313 case LibFunc::bcopy:
314 Changed |= setDoesNotThrow(F);
315 Changed |= setDoesNotCapture(F, 1);
316 Changed |= setDoesNotCapture(F, 2);
317 Changed |= setOnlyReadsMemory(F, 1);
318 return Changed;
319 case LibFunc::bcmp:
320 Changed |= setDoesNotThrow(F);
321 Changed |= setOnlyReadsMemory(F);
322 Changed |= setDoesNotCapture(F, 1);
323 Changed |= setDoesNotCapture(F, 2);
324 return Changed;
325 case LibFunc::bzero:
326 Changed |= setDoesNotThrow(F);
327 Changed |= setDoesNotCapture(F, 1);
328 return Changed;
329 case LibFunc::calloc:
330 Changed |= setDoesNotThrow(F);
331 Changed |= setDoesNotAlias(F, 0);
332 return Changed;
333 case LibFunc::chmod:
334 case LibFunc::chown:
335 Changed |= setDoesNotThrow(F);
336 Changed |= setDoesNotCapture(F, 1);
337 Changed |= setOnlyReadsMemory(F, 1);
338 return Changed;
339 case LibFunc::ctermid:
340 case LibFunc::clearerr:
341 case LibFunc::closedir:
342 Changed |= setDoesNotThrow(F);
343 Changed |= setDoesNotCapture(F, 1);
344 return Changed;
345 case LibFunc::atoi:
346 case LibFunc::atol:
347 case LibFunc::atof:
348 case LibFunc::atoll:
349 Changed |= setDoesNotThrow(F);
350 Changed |= setOnlyReadsMemory(F);
351 Changed |= setDoesNotCapture(F, 1);
352 return Changed;
353 case LibFunc::access:
354 Changed |= setDoesNotThrow(F);
355 Changed |= setDoesNotCapture(F, 1);
356 Changed |= setOnlyReadsMemory(F, 1);
357 return Changed;
358 case LibFunc::fopen:
359 Changed |= setDoesNotThrow(F);
360 Changed |= setDoesNotAlias(F, 0);
361 Changed |= setDoesNotCapture(F, 1);
362 Changed |= setDoesNotCapture(F, 2);
363 Changed |= setOnlyReadsMemory(F, 1);
364 Changed |= setOnlyReadsMemory(F, 2);
365 return Changed;
366 case LibFunc::fdopen:
367 Changed |= setDoesNotThrow(F);
368 Changed |= setDoesNotAlias(F, 0);
369 Changed |= setDoesNotCapture(F, 2);
370 Changed |= setOnlyReadsMemory(F, 2);
371 return Changed;
372 case LibFunc::feof:
373 case LibFunc::free:
374 case LibFunc::fseek:
375 case LibFunc::ftell:
376 case LibFunc::fgetc:
377 case LibFunc::fseeko:
378 case LibFunc::ftello:
379 case LibFunc::fileno:
380 case LibFunc::fflush:
381 case LibFunc::fclose:
382 case LibFunc::fsetpos:
383 case LibFunc::flockfile:
384 case LibFunc::funlockfile:
385 case LibFunc::ftrylockfile:
386 Changed |= setDoesNotThrow(F);
387 Changed |= setDoesNotCapture(F, 1);
388 return Changed;
389 case LibFunc::ferror:
390 Changed |= setDoesNotThrow(F);
391 Changed |= setDoesNotCapture(F, 1);
392 Changed |= setOnlyReadsMemory(F);
393 return Changed;
394 case LibFunc::fputc:
395 case LibFunc::fstat:
396 case LibFunc::frexp:
397 case LibFunc::frexpf:
398 case LibFunc::frexpl:
399 case LibFunc::fstatvfs:
400 Changed |= setDoesNotThrow(F);
401 Changed |= setDoesNotCapture(F, 2);
402 return Changed;
403 case LibFunc::fgets:
404 Changed |= setDoesNotThrow(F);
405 Changed |= setDoesNotCapture(F, 3);
406 return Changed;
407 case LibFunc::fread:
408 Changed |= setDoesNotThrow(F);
409 Changed |= setDoesNotCapture(F, 1);
410 Changed |= setDoesNotCapture(F, 4);
411 return Changed;
412 case LibFunc::fwrite:
413 Changed |= setDoesNotThrow(F);
414 Changed |= setDoesNotCapture(F, 1);
415 Changed |= setDoesNotCapture(F, 4);
416 // FIXME: readonly #1?
417 return Changed;
418 case LibFunc::fputs:
419 Changed |= setDoesNotThrow(F);
420 Changed |= setDoesNotCapture(F, 1);
421 Changed |= setDoesNotCapture(F, 2);
422 Changed |= setOnlyReadsMemory(F, 1);
423 return Changed;
424 case LibFunc::fscanf:
425 case LibFunc::fprintf:
426 Changed |= setDoesNotThrow(F);
427 Changed |= setDoesNotCapture(F, 1);
428 Changed |= setDoesNotCapture(F, 2);
429 Changed |= setOnlyReadsMemory(F, 2);
430 return Changed;
431 case LibFunc::fgetpos:
432 Changed |= setDoesNotThrow(F);
433 Changed |= setDoesNotCapture(F, 1);
434 Changed |= setDoesNotCapture(F, 2);
435 return Changed;
436 case LibFunc::getc:
437 case LibFunc::getlogin_r:
438 case LibFunc::getc_unlocked:
439 Changed |= setDoesNotThrow(F);
440 Changed |= setDoesNotCapture(F, 1);
441 return Changed;
442 case LibFunc::getenv:
443 Changed |= setDoesNotThrow(F);
444 Changed |= setOnlyReadsMemory(F);
445 Changed |= setDoesNotCapture(F, 1);
446 return Changed;
447 case LibFunc::gets:
448 case LibFunc::getchar:
449 Changed |= setDoesNotThrow(F);
450 return Changed;
451 case LibFunc::getitimer:
452 Changed |= setDoesNotThrow(F);
453 Changed |= setDoesNotCapture(F, 2);
454 return Changed;
455 case LibFunc::getpwnam:
456 Changed |= setDoesNotThrow(F);
457 Changed |= setDoesNotCapture(F, 1);
458 Changed |= setOnlyReadsMemory(F, 1);
459 return Changed;
460 case LibFunc::ungetc:
461 Changed |= setDoesNotThrow(F);
462 Changed |= setDoesNotCapture(F, 2);
463 return Changed;
464 case LibFunc::uname:
465 Changed |= setDoesNotThrow(F);
466 Changed |= setDoesNotCapture(F, 1);
467 return Changed;
468 case LibFunc::unlink:
469 Changed |= setDoesNotThrow(F);
470 Changed |= setDoesNotCapture(F, 1);
471 Changed |= setOnlyReadsMemory(F, 1);
472 return Changed;
473 case LibFunc::unsetenv:
474 Changed |= setDoesNotThrow(F);
475 Changed |= setDoesNotCapture(F, 1);
476 Changed |= setOnlyReadsMemory(F, 1);
477 return Changed;
478 case LibFunc::utime:
479 case LibFunc::utimes:
480 Changed |= setDoesNotThrow(F);
481 Changed |= setDoesNotCapture(F, 1);
482 Changed |= setDoesNotCapture(F, 2);
483 Changed |= setOnlyReadsMemory(F, 1);
484 Changed |= setOnlyReadsMemory(F, 2);
485 return Changed;
486 case LibFunc::putc:
487 Changed |= setDoesNotThrow(F);
488 Changed |= setDoesNotCapture(F, 2);
489 return Changed;
490 case LibFunc::puts:
491 case LibFunc::printf:
492 case LibFunc::perror:
493 Changed |= setDoesNotThrow(F);
494 Changed |= setDoesNotCapture(F, 1);
495 Changed |= setOnlyReadsMemory(F, 1);
496 return Changed;
497 case LibFunc::pread:
498 // May throw; "pread" is a valid pthread cancellation point.
499 Changed |= setDoesNotCapture(F, 2);
500 return Changed;
501 case LibFunc::pwrite:
502 // May throw; "pwrite" is a valid pthread cancellation point.
503 Changed |= setDoesNotCapture(F, 2);
504 Changed |= setOnlyReadsMemory(F, 2);
505 return Changed;
506 case LibFunc::putchar:
507 Changed |= setDoesNotThrow(F);
508 return Changed;
509 case LibFunc::popen:
510 Changed |= setDoesNotThrow(F);
511 Changed |= setDoesNotAlias(F, 0);
512 Changed |= setDoesNotCapture(F, 1);
513 Changed |= setDoesNotCapture(F, 2);
514 Changed |= setOnlyReadsMemory(F, 1);
515 Changed |= setOnlyReadsMemory(F, 2);
516 return Changed;
517 case LibFunc::pclose:
518 Changed |= setDoesNotThrow(F);
519 Changed |= setDoesNotCapture(F, 1);
520 return Changed;
521 case LibFunc::vscanf:
522 Changed |= setDoesNotThrow(F);
523 Changed |= setDoesNotCapture(F, 1);
524 Changed |= setOnlyReadsMemory(F, 1);
525 return Changed;
526 case LibFunc::vsscanf:
527 Changed |= setDoesNotThrow(F);
528 Changed |= setDoesNotCapture(F, 1);
529 Changed |= setDoesNotCapture(F, 2);
530 Changed |= setOnlyReadsMemory(F, 1);
531 Changed |= setOnlyReadsMemory(F, 2);
532 return Changed;
533 case LibFunc::vfscanf:
534 Changed |= setDoesNotThrow(F);
535 Changed |= setDoesNotCapture(F, 1);
536 Changed |= setDoesNotCapture(F, 2);
537 Changed |= setOnlyReadsMemory(F, 2);
538 return Changed;
539 case LibFunc::valloc:
540 Changed |= setDoesNotThrow(F);
541 Changed |= setDoesNotAlias(F, 0);
542 return Changed;
543 case LibFunc::vprintf:
544 Changed |= setDoesNotThrow(F);
545 Changed |= setDoesNotCapture(F, 1);
546 Changed |= setOnlyReadsMemory(F, 1);
547 return Changed;
548 case LibFunc::vfprintf:
549 case LibFunc::vsprintf:
550 Changed |= setDoesNotThrow(F);
551 Changed |= setDoesNotCapture(F, 1);
552 Changed |= setDoesNotCapture(F, 2);
553 Changed |= setOnlyReadsMemory(F, 2);
554 return Changed;
555 case LibFunc::vsnprintf:
556 Changed |= setDoesNotThrow(F);
557 Changed |= setDoesNotCapture(F, 1);
558 Changed |= setDoesNotCapture(F, 3);
559 Changed |= setOnlyReadsMemory(F, 3);
560 return Changed;
561 case LibFunc::open:
562 // May throw; "open" is a valid pthread cancellation point.
563 Changed |= setDoesNotCapture(F, 1);
564 Changed |= setOnlyReadsMemory(F, 1);
565 return Changed;
566 case LibFunc::opendir:
567 Changed |= setDoesNotThrow(F);
568 Changed |= setDoesNotAlias(F, 0);
569 Changed |= setDoesNotCapture(F, 1);
570 Changed |= setOnlyReadsMemory(F, 1);
571 return Changed;
572 case LibFunc::tmpfile:
573 Changed |= setDoesNotThrow(F);
574 Changed |= setDoesNotAlias(F, 0);
575 return Changed;
576 case LibFunc::times:
577 Changed |= setDoesNotThrow(F);
578 Changed |= setDoesNotCapture(F, 1);
579 return Changed;
580 case LibFunc::htonl:
581 case LibFunc::htons:
582 case LibFunc::ntohl:
583 case LibFunc::ntohs:
584 Changed |= setDoesNotThrow(F);
585 Changed |= setDoesNotAccessMemory(F);
586 return Changed;
587 case LibFunc::lstat:
588 Changed |= setDoesNotThrow(F);
589 Changed |= setDoesNotCapture(F, 1);
590 Changed |= setDoesNotCapture(F, 2);
591 Changed |= setOnlyReadsMemory(F, 1);
592 return Changed;
593 case LibFunc::lchown:
594 Changed |= setDoesNotThrow(F);
595 Changed |= setDoesNotCapture(F, 1);
596 Changed |= setOnlyReadsMemory(F, 1);
597 return Changed;
598 case LibFunc::qsort:
599 // May throw; places call through function pointer.
600 Changed |= setDoesNotCapture(F, 4);
601 return Changed;
602 case LibFunc::dunder_strdup:
603 case LibFunc::dunder_strndup:
604 Changed |= setDoesNotThrow(F);
605 Changed |= setDoesNotAlias(F, 0);
606 Changed |= setDoesNotCapture(F, 1);
607 Changed |= setOnlyReadsMemory(F, 1);
608 return Changed;
609 case LibFunc::dunder_strtok_r:
610 Changed |= setDoesNotThrow(F);
611 Changed |= setDoesNotCapture(F, 2);
612 Changed |= setOnlyReadsMemory(F, 2);
613 return Changed;
614 case LibFunc::under_IO_getc:
615 Changed |= setDoesNotThrow(F);
616 Changed |= setDoesNotCapture(F, 1);
617 return Changed;
618 case LibFunc::under_IO_putc:
619 Changed |= setDoesNotThrow(F);
620 Changed |= setDoesNotCapture(F, 2);
621 return Changed;
622 case LibFunc::dunder_isoc99_scanf:
623 Changed |= setDoesNotThrow(F);
624 Changed |= setDoesNotCapture(F, 1);
625 Changed |= setOnlyReadsMemory(F, 1);
626 return Changed;
627 case LibFunc::stat64:
628 case LibFunc::lstat64:
629 case LibFunc::statvfs64:
630 Changed |= setDoesNotThrow(F);
631 Changed |= setDoesNotCapture(F, 1);
632 Changed |= setDoesNotCapture(F, 2);
633 Changed |= setOnlyReadsMemory(F, 1);
634 return Changed;
635 case LibFunc::dunder_isoc99_sscanf:
636 Changed |= setDoesNotThrow(F);
637 Changed |= setDoesNotCapture(F, 1);
638 Changed |= setDoesNotCapture(F, 2);
639 Changed |= setOnlyReadsMemory(F, 1);
640 Changed |= setOnlyReadsMemory(F, 2);
641 return Changed;
642 case LibFunc::fopen64:
643 Changed |= setDoesNotThrow(F);
644 Changed |= setDoesNotAlias(F, 0);
645 Changed |= setDoesNotCapture(F, 1);
646 Changed |= setDoesNotCapture(F, 2);
647 Changed |= setOnlyReadsMemory(F, 1);
648 Changed |= setOnlyReadsMemory(F, 2);
649 return Changed;
650 case LibFunc::fseeko64:
651 case LibFunc::ftello64:
652 Changed |= setDoesNotThrow(F);
653 Changed |= setDoesNotCapture(F, 1);
654 return Changed;
655 case LibFunc::tmpfile64:
656 Changed |= setDoesNotThrow(F);
657 Changed |= setDoesNotAlias(F, 0);
658 return Changed;
659 case LibFunc::fstat64:
660 case LibFunc::fstatvfs64:
661 Changed |= setDoesNotThrow(F);
662 Changed |= setDoesNotCapture(F, 2);
663 return Changed;
664 case LibFunc::open64:
665 // May throw; "open" is a valid pthread cancellation point.
666 Changed |= setDoesNotCapture(F, 1);
667 Changed |= setOnlyReadsMemory(F, 1);
668 return Changed;
669 case LibFunc::gettimeofday:
670 // Currently some platforms have the restrict keyword on the arguments to
671 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
672 // arguments.
673 Changed |= setDoesNotThrow(F);
674 Changed |= setDoesNotCapture(F, 1);
675 Changed |= setDoesNotCapture(F, 2);
676 return Changed;
677 case LibFunc::Znwj: // new(unsigned int)
678 case LibFunc::Znwm: // new(unsigned long)
679 case LibFunc::Znaj: // new[](unsigned int)
680 case LibFunc::Znam: // new[](unsigned long)
681 case LibFunc::msvc_new_int: // new(unsigned int)
682 case LibFunc::msvc_new_longlong: // new(unsigned long long)
683 case LibFunc::msvc_new_array_int: // new[](unsigned int)
684 case LibFunc::msvc_new_array_longlong: // new[](unsigned long long)
685 // Operator new always returns a nonnull noalias pointer
686 Changed |= setNonNull(F, AttributeSet::ReturnIndex);
687 Changed |= setDoesNotAlias(F, AttributeSet::ReturnIndex);
688 return Changed;
689 //TODO: add LibFunc entries for:
690 //case LibFunc::memset_pattern4:
691 //case LibFunc::memset_pattern8:
692 case LibFunc::memset_pattern16:
693 Changed |= setOnlyAccessesArgMemory(F);
Ahmed Bougacha44c19872016-04-27 19:04:43 +0000694 Changed |= setDoesNotCapture(F, 1);
695 Changed |= setDoesNotCapture(F, 2);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000696 Changed |= setOnlyReadsMemory(F, 2);
697 return Changed;
698 // int __nvvm_reflect(const char *)
699 case LibFunc::nvvm_reflect:
700 Changed |= setDoesNotAccessMemory(F);
701 Changed |= setDoesNotThrow(F);
702 return Changed;
703
704 default:
705 // FIXME: It'd be really nice to cover all the library functions we're
706 // aware of here.
707 return false;
708 }
709}
710
711//- Emit LibCalls ------------------------------------------------------------//
712
Sanjay Pateld3112a52016-01-19 19:46:10 +0000713Value *llvm::castToCStr(Value *V, IRBuilder<> &B) {
Matt Arsenaultbe558882014-04-23 20:58:57 +0000714 unsigned AS = V->getType()->getPointerAddressSpace();
715 return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr");
Eric Christopher87abfc52010-03-05 22:25:30 +0000716}
717
Sanjay Pateld3112a52016-01-19 19:46:10 +0000718Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000719 const TargetLibraryInfo *TLI) {
720 if (!TLI->has(LibFunc::strlen))
Craig Topperf40110f2014-04-25 05:29:35 +0000721 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000722
Sanjay Pateld4af2972016-01-19 19:58:49 +0000723 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000724 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000725 Constant *StrLen = M->getOrInsertFunction("strlen", DL.getIntPtrType(Context),
726 B.getInt8PtrTy(), nullptr);
727 inferLibFuncAttributes(*M->getFunction("strlen"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000728 CallInst *CI = B.CreateCall(StrLen, castToCStr(Ptr, B), "strlen");
Evan Chengad6efbf2014-03-12 18:09:37 +0000729 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
730 CI->setCallingConv(F->getCallingConv());
731
Eric Christopher87abfc52010-03-05 22:25:30 +0000732 return CI;
733}
734
Sanjay Pateld3112a52016-01-19 19:46:10 +0000735Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000736 const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000737 if (!TLI->has(LibFunc::strchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000738 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000739
Sanjay Pateld4af2972016-01-19 19:58:49 +0000740 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000741 Type *I8Ptr = B.getInt8PtrTy();
742 Type *I32Ty = B.getInt32Ty();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000743 Constant *StrChr =
744 M->getOrInsertFunction("strchr", I8Ptr, I8Ptr, I32Ty, nullptr);
745 inferLibFuncAttributes(*M->getFunction("strchr"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000746 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000747 StrChr, {castToCStr(Ptr, B), ConstantInt::get(I32Ty, C)}, "strchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000748 if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
749 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000750 return CI;
751}
752
Sanjay Pateld3112a52016-01-19 19:46:10 +0000753Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000754 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000755 if (!TLI->has(LibFunc::strncmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000756 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000757
Sanjay Pateld4af2972016-01-19 19:58:49 +0000758 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000759 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000760 Value *StrNCmp = M->getOrInsertFunction("strncmp", B.getInt32Ty(),
761 B.getInt8PtrTy(), B.getInt8PtrTy(),
762 DL.getIntPtrType(Context), nullptr);
763 inferLibFuncAttributes(*M->getFunction("strncmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000764 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000765 StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000766
767 if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
768 CI->setCallingConv(F->getCallingConv());
769
Benjamin Kramer11188602010-06-15 21:34:25 +0000770 return CI;
771}
772
Sanjay Pateld3112a52016-01-19 19:46:10 +0000773Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000774 const TargetLibraryInfo *TLI, StringRef Name) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000775 if (!TLI->has(LibFunc::strcpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000776 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000777
Sanjay Pateld4af2972016-01-19 19:58:49 +0000778 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000779 Type *I8Ptr = B.getInt8PtrTy();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000780 Value *StrCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr, nullptr);
781 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000782 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +0000783 B.CreateCall(StrCpy, {castToCStr(Dst, B), castToCStr(Src, B)}, Name);
Evan Chengad6efbf2014-03-12 18:09:37 +0000784 if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
785 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000786 return CI;
787}
788
Sanjay Pateld3112a52016-01-19 19:46:10 +0000789Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000790 const TargetLibraryInfo *TLI, StringRef Name) {
791 if (!TLI->has(LibFunc::strncpy))
Craig Topperf40110f2014-04-25 05:29:35 +0000792 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000793
Sanjay Pateld4af2972016-01-19 19:58:49 +0000794 Module *M = B.GetInsertBlock()->getModule();
Chris Lattner229907c2011-07-18 04:54:35 +0000795 Type *I8Ptr = B.getInt8PtrTy();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000796 Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr,
Reid Kleckner971c3ea2014-11-13 22:55:19 +0000797 Len->getType(), nullptr);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000798 inferLibFuncAttributes(*M->getFunction(Name), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000799 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000800 StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy");
Evan Chengad6efbf2014-03-12 18:09:37 +0000801 if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
802 CI->setCallingConv(F->getCallingConv());
Eric Christopher43dc11c2010-03-11 01:25:07 +0000803 return CI;
804}
805
Sanjay Pateld3112a52016-01-19 19:46:10 +0000806Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000807 IRBuilder<> &B, const DataLayout &DL,
Nuno Lopes89702e92012-07-25 16:46:31 +0000808 const TargetLibraryInfo *TLI) {
809 if (!TLI->has(LibFunc::memcpy_chk))
Craig Topperf40110f2014-04-25 05:29:35 +0000810 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000811
Sanjay Pateld4af2972016-01-19 19:58:49 +0000812 Module *M = B.GetInsertBlock()->getModule();
Bill Wendling201d7b22013-01-26 00:03:11 +0000813 AttributeSet AS;
814 AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
815 Attribute::NoUnwind);
Chandler Carruth7ec50852012-11-01 08:07:29 +0000816 LLVMContext &Context = B.GetInsertBlock()->getContext();
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000817 Value *MemCpy = M->getOrInsertFunction(
818 "__memcpy_chk", AttributeSet::get(M->getContext(), AS), B.getInt8PtrTy(),
819 B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context),
820 DL.getIntPtrType(Context), nullptr);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000821 Dst = castToCStr(Dst, B);
822 Src = castToCStr(Src, B);
David Blaikieff6409d2015-05-18 22:13:54 +0000823 CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});
Evan Chengad6efbf2014-03-12 18:09:37 +0000824 if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
825 CI->setCallingConv(F->getCallingConv());
Evan Chengd9e82232010-03-23 15:48:04 +0000826 return CI;
827}
828
Sanjay Pateld3112a52016-01-19 19:46:10 +0000829Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000830 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000831 if (!TLI->has(LibFunc::memchr))
Craig Topperf40110f2014-04-25 05:29:35 +0000832 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000833
Sanjay Pateld4af2972016-01-19 19:58:49 +0000834 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000835 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000836 Value *MemChr = M->getOrInsertFunction("memchr", B.getInt8PtrTy(),
837 B.getInt8PtrTy(), B.getInt32Ty(),
838 DL.getIntPtrType(Context), nullptr);
839 inferLibFuncAttributes(*M->getFunction("memchr"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000840 CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr");
Evan Chengad6efbf2014-03-12 18:09:37 +0000841
842 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
843 CI->setCallingConv(F->getCallingConv());
844
Eric Christopher87abfc52010-03-05 22:25:30 +0000845 return CI;
846}
847
Sanjay Pateld3112a52016-01-19 19:46:10 +0000848Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000849 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000850 if (!TLI->has(LibFunc::memcmp))
Craig Topperf40110f2014-04-25 05:29:35 +0000851 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000852
Sanjay Pateld4af2972016-01-19 19:58:49 +0000853 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000854 LLVMContext &Context = B.GetInsertBlock()->getContext();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000855 Value *MemCmp = M->getOrInsertFunction("memcmp", B.getInt32Ty(),
856 B.getInt8PtrTy(), B.getInt8PtrTy(),
857 DL.getIntPtrType(Context), nullptr);
858 inferLibFuncAttributes(*M->getFunction("memcmp"), *TLI);
David Blaikieff6409d2015-05-18 22:13:54 +0000859 CallInst *CI = B.CreateCall(
Sanjay Pateld3112a52016-01-19 19:46:10 +0000860 MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp");
Evan Chengad6efbf2014-03-12 18:09:37 +0000861
862 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
863 CI->setCallingConv(F->getCallingConv());
864
Eric Christopher87abfc52010-03-05 22:25:30 +0000865 return CI;
866}
867
Yi Jiang6ab044e2013-12-16 22:42:40 +0000868/// Append a suffix to the function name according to the type of 'Op'.
Sanjay Pateld3112a52016-01-19 19:46:10 +0000869static void appendTypeSuffix(Value *Op, StringRef &Name,
Sanjay Patelb50325e2016-01-19 19:17:47 +0000870 SmallString<20> &NameBuffer) {
Yi Jiang6ab044e2013-12-16 22:42:40 +0000871 if (!Op->getType()->isDoubleTy()) {
872 NameBuffer += Name;
873
874 if (Op->getType()->isFloatTy())
875 NameBuffer += 'f';
876 else
877 NameBuffer += 'l';
878
879 Name = NameBuffer;
880 }
Yi Jiang6ab044e2013-12-16 22:42:40 +0000881}
882
Sanjay Pateld3112a52016-01-19 19:46:10 +0000883Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
Bill Wendlinge94d8432012-12-07 23:16:57 +0000884 const AttributeSet &Attrs) {
Benjamin Kramerb106bcc2011-11-15 19:12:09 +0000885 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000886 appendTypeSuffix(Op, Name, NameBuffer);
Eric Christopher87abfc52010-03-05 22:25:30 +0000887
Sanjay Pateld4af2972016-01-19 19:58:49 +0000888 Module *M = B.GetInsertBlock()->getModule();
Eric Christopher87abfc52010-03-05 22:25:30 +0000889 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Reid Kleckner971c3ea2014-11-13 22:55:19 +0000890 Op->getType(), nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000891 CallInst *CI = B.CreateCall(Callee, Op, Name);
892 CI->setAttributes(Attrs);
Evan Chengad6efbf2014-03-12 18:09:37 +0000893 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
894 CI->setCallingConv(F->getCallingConv());
895
Eric Christopher87abfc52010-03-05 22:25:30 +0000896 return CI;
897}
898
Sanjay Pateld3112a52016-01-19 19:46:10 +0000899Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
Yi Jiang6ab044e2013-12-16 22:42:40 +0000900 IRBuilder<> &B, const AttributeSet &Attrs) {
901 SmallString<20> NameBuffer;
Sanjay Pateld3112a52016-01-19 19:46:10 +0000902 appendTypeSuffix(Op1, Name, NameBuffer);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000903
Sanjay Pateld4af2972016-01-19 19:58:49 +0000904 Module *M = B.GetInsertBlock()->getModule();
Sanjay Patelb50325e2016-01-19 19:17:47 +0000905 Value *Callee = M->getOrInsertFunction(Name, Op1->getType(), Op1->getType(),
906 Op2->getType(), nullptr);
David Blaikieff6409d2015-05-18 22:13:54 +0000907 CallInst *CI = B.CreateCall(Callee, {Op1, Op2}, Name);
Yi Jiang6ab044e2013-12-16 22:42:40 +0000908 CI->setAttributes(Attrs);
Evan Chengad6efbf2014-03-12 18:09:37 +0000909 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
910 CI->setCallingConv(F->getCallingConv());
911
Yi Jiang6ab044e2013-12-16 22:42:40 +0000912 return CI;
913}
914
Sanjay Pateld3112a52016-01-19 19:46:10 +0000915Value *llvm::emitPutChar(Value *Char, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000916 const TargetLibraryInfo *TLI) {
917 if (!TLI->has(LibFunc::putchar))
Craig Topperf40110f2014-04-25 05:29:35 +0000918 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000919
Sanjay Pateld4af2972016-01-19 19:58:49 +0000920 Module *M = B.GetInsertBlock()->getModule();
Eric Christopher87abfc52010-03-05 22:25:30 +0000921 Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
Reid Kleckner971c3ea2014-11-13 22:55:19 +0000922 B.getInt32Ty(), nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000923 CallInst *CI = B.CreateCall(PutChar,
924 B.CreateIntCast(Char,
925 B.getInt32Ty(),
926 /*isSigned*/true,
927 "chari"),
928 "putchar");
Evan Chengad6efbf2014-03-12 18:09:37 +0000929
930 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
931 CI->setCallingConv(F->getCallingConv());
Eric Christopher87abfc52010-03-05 22:25:30 +0000932 return CI;
933}
934
Sanjay Pateld3112a52016-01-19 19:46:10 +0000935Value *llvm::emitPutS(Value *Str, IRBuilder<> &B,
Nuno Lopes89702e92012-07-25 16:46:31 +0000936 const TargetLibraryInfo *TLI) {
937 if (!TLI->has(LibFunc::puts))
Craig Topperf40110f2014-04-25 05:29:35 +0000938 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000939
Sanjay Pateld4af2972016-01-19 19:58:49 +0000940 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000941 Value *PutS =
942 M->getOrInsertFunction("puts", B.getInt32Ty(), B.getInt8PtrTy(), nullptr);
943 inferLibFuncAttributes(*M->getFunction("puts"), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000944 CallInst *CI = B.CreateCall(PutS, castToCStr(Str, B), "puts");
Evan Chengad6efbf2014-03-12 18:09:37 +0000945 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
946 CI->setCallingConv(F->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000947 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000948}
949
Sanjay Pateld3112a52016-01-19 19:46:10 +0000950Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000951 const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000952 if (!TLI->has(LibFunc::fputc))
Craig Topperf40110f2014-04-25 05:29:35 +0000953 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000954
Sanjay Pateld4af2972016-01-19 19:58:49 +0000955 Module *M = B.GetInsertBlock()->getModule();
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000956 Constant *F = M->getOrInsertFunction("fputc", B.getInt32Ty(), B.getInt32Ty(),
957 File->getType(), nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000958 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000959 inferLibFuncAttributes(*M->getFunction("fputc"), *TLI);
Eric Christopher87abfc52010-03-05 22:25:30 +0000960 Char = B.CreateIntCast(Char, B.getInt32Ty(), /*isSigned*/true,
961 "chari");
David Blaikieff6409d2015-05-18 22:13:54 +0000962 CallInst *CI = B.CreateCall(F, {Char, File}, "fputc");
Evan Chengad6efbf2014-03-12 18:09:37 +0000963
964 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
965 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000966 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000967}
968
Sanjay Pateld3112a52016-01-19 19:46:10 +0000969Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000970 const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000971 if (!TLI->has(LibFunc::fputs))
Craig Topperf40110f2014-04-25 05:29:35 +0000972 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000973
Sanjay Pateld4af2972016-01-19 19:58:49 +0000974 Module *M = B.GetInsertBlock()->getModule();
Eli Friedman489c0ff2011-11-17 01:27:36 +0000975 StringRef FPutsName = TLI->getName(LibFunc::fputs);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000976 Constant *F = M->getOrInsertFunction(
977 FPutsName, B.getInt32Ty(), B.getInt8PtrTy(), File->getType(), nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000978 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000979 inferLibFuncAttributes(*M->getFunction(FPutsName), *TLI);
Sanjay Pateld3112a52016-01-19 19:46:10 +0000980 CallInst *CI = B.CreateCall(F, {castToCStr(Str, B), File}, "fputs");
Evan Chengad6efbf2014-03-12 18:09:37 +0000981
982 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
983 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +0000984 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +0000985}
986
Sanjay Pateld3112a52016-01-19 19:46:10 +0000987Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000988 const DataLayout &DL, const TargetLibraryInfo *TLI) {
Nuno Lopes89702e92012-07-25 16:46:31 +0000989 if (!TLI->has(LibFunc::fwrite))
Craig Topperf40110f2014-04-25 05:29:35 +0000990 return nullptr;
Nuno Lopes89702e92012-07-25 16:46:31 +0000991
Sanjay Pateld4af2972016-01-19 19:58:49 +0000992 Module *M = B.GetInsertBlock()->getModule();
Chandler Carruth7ec50852012-11-01 08:07:29 +0000993 LLVMContext &Context = B.GetInsertBlock()->getContext();
Eli Friedman489c0ff2011-11-17 01:27:36 +0000994 StringRef FWriteName = TLI->getName(LibFunc::fwrite);
Ahmed Bougachab0624a22016-04-27 19:04:40 +0000995 Constant *F = M->getOrInsertFunction(
996 FWriteName, DL.getIntPtrType(Context), B.getInt8PtrTy(),
997 DL.getIntPtrType(Context), DL.getIntPtrType(Context), File->getType(),
998 nullptr);
Eric Christopher87abfc52010-03-05 22:25:30 +0000999 if (File->getType()->isPointerTy())
Ahmed Bougachab0624a22016-04-27 19:04:40 +00001000 inferLibFuncAttributes(*M->getFunction(FWriteName), *TLI);
Mehdi Aminia28d91d2015-03-10 02:37:25 +00001001 CallInst *CI =
Sanjay Pateld3112a52016-01-19 19:46:10 +00001002 B.CreateCall(F, {castToCStr(Ptr, B), Size,
David Blaikieff6409d2015-05-18 22:13:54 +00001003 ConstantInt::get(DL.getIntPtrType(Context), 1), File});
Evan Chengad6efbf2014-03-12 18:09:37 +00001004
1005 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
1006 CI->setCallingConv(Fn->getCallingConv());
Nuno Lopes89702e92012-07-25 16:46:31 +00001007 return CI;
Eric Christopher87abfc52010-03-05 22:25:30 +00001008}