This is an archive of the discontinued LLVM Phabricator instance.

[libc] add printf
ClosedPublic

Authored by michaelrj on Jun 1 2022, 3:03 PM.

Details

Summary

This patch adds the entrypoint for printf. With this, building a
"hello world" program with just LLVM-libc is possible.

Diff Detail

Event Timeline

michaelrj created this revision.Jun 1 2022, 3:03 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJun 1 2022, 3:03 PM
michaelrj requested review of this revision.Jun 1 2022, 3:03 PM
sivachandra added inline comments.Jun 2 2022, 1:26 AM
libc/src/stdio/printf.cpp
35

You don't need to cast to FILE * and call ferror. You can directly call the error method.

Also, a use case like this makes me feel that the writer functions should return an int value which can be consumed by printf_main to process the error. That way, the file writer can write_unlocked and error_unlocked under a single lock/unlock.

michaelrj updated this revision to Diff 434204.Jun 3 2022, 4:42 PM
michaelrj marked an inline comment as done.

switch to unlocked writes with the lock aquisition happening before the parsing. Additionally track errors better.

michaelrj edited the summary of this revision. (Show Details)Jun 3 2022, 4:42 PM
sivachandra added inline comments.Jun 10 2022, 12:12 PM
libc/src/stdio/printf.cpp
33

Nit: There is an RAII file lock:

__llvm_libc::File::FileLock lock(__llvm_libc::stdout);

Couple of things more:

  1. It seems to me like this is not the place to do the lock/unlock and call to error_unlocked. It should be managed by the file writer and the errors should be surfaced to printf_main. See another comment below.
  2. printf and fprintf should share code in some manner instead of being mostly duplicated.
libc/src/stdio/printf_core/writer.h
41 ↗(On Diff #435960)

If this method returns an int value, which can be negative on error, printf_main can do an early return as soon as it sees an error. If this is OK, you should do the same with the converter functions. Why is that not a preferred design?

michaelrj updated this revision to Diff 436605.Jun 13 2022, 4:47 PM
michaelrj marked 2 inline comments as done.

move shared fprintf functionality into internal function, as well as other cleanups

libc/src/stdio/printf.cpp
33

For the file lock class, that isn't a public class so I can't access it here.

I've moved some error handling to printf_main.
As for managing the long in the file writer, the problem is that there is no file writer. Since the FILE class already exposes the interface needed, the write_to_file function just uses the raw FILE. While I could create a class just to hold a lock and destroy it on exit, that seems a bit overkill when I can just call the lock and unlock functions by hand.

I've moved the shared printf and fprintf implementation into vfprintf_internal.

libc/src/stdio/printf_core/writer.h
41 ↗(On Diff #435960)

It's not a preferred design because write may be called multiple times in a single function. Int conversion uses up to 4 calls. Having an if result < 0 after each of those would be very inefficient, and more importantly not particularly helpful. Usually if a write fails, then all subsequent writes will also fail, so I think it's best to not check every write, instead check the status of the writer every loop. I've added a condition in printf_main to do just that.

sivachandra added inline comments.Jun 13 2022, 10:12 PM
libc/src/stdio/printf.cpp
33

No, that is not an overkill - you are keeping all file operations cohesively managed by the FileWriter.

+1 for the vfprintf_internal refactoring.

libc/src/stdio/printf_core/writer.h
41 ↗(On Diff #435960)

Normal design practice would be to return as soon as you see an error. We should follow that until we have sufficient evidence that conditionals like that are the source of a performance problem. Even if we can conclude that conditionals like that are a performance problem, a potential solution should investigate other kind of refactorings which reduce conditionals while stopping as soon as an error is detected.

michaelrj marked 2 inline comments as done.

I split the file handling rewrite into its own separate patch after addressing the comments (https://reviews.llvm.org/D127773), this is now just adding true printf.

michaelrj edited the summary of this revision. (Show Details)Jun 14 2022, 12:08 PM
sivachandra accepted this revision.Jun 15 2022, 11:26 AM
This revision is now accepted and ready to land.Jun 15 2022, 11:26 AM
This revision was landed with ongoing or failed builds.Jun 15 2022, 11:45 AM
Closed by commit rGad233c6047fc: [libc] add printf (authored by michaelrj). · Explain Why
This revision was automatically updated to reflect the committed changes.