clang/LLVM

Cross-language link-time optimization using Red Hat Developer Tools

Cross-language link-time optimization using Red Hat Developer Tools

Several months ago, the LLVM project blog published an article, Closing the gap: cross-language LTO between Rust and C/C++. In it, they explained that link-time optimization can improve performance by optimizing throughout the whole program, such as inlining function calls between different objects. Since Rust and Clang both use LLVM for code generation, we can even achieve this benefit across different programming languages.

In Red Hat Developer Tools, we have the Rust and LLVM Toolsets, which can easily be used together for cross-language link-time optimization (LTO), so let’s try it out.

Continue reading “Cross-language link-time optimization using Red Hat Developer Tools”

Share
Toward _FORTIFY_SOURCE parity between Clang and GCC

Toward _FORTIFY_SOURCE parity between Clang and GCC

GCC combined with glibc can detect instances of buffer overflow by standard C library functions. When a user passes the -D_FORTIFY_SOURCE={1,2} preprocessor flag and an optimization level greater or equal to -O1, an alternate, fortified implementation of the function is used when calling, say, strcpy. Depending on the function and its inputs, this behavior may result in a compile-time error, or a runtime error triggered upon execution. (For more info on this feature, there’s an excellent blog post here on the subject).

Continue reading Toward _FORTIFY_SOURCE parity between Clang and GCC

Share
MIR: A lightweight JIT compiler project

MIR: A lightweight JIT compiler project

For the past three years, I’ve been participating in adding just-in-time compilation (JIT) to CRuby. Now, CRuby has the method-based just-in-time compiler (MJIT), which improves performance for non-input/output-bound programs.

The most popular approach to implementing a JIT is to use LLVM or GCC JIT interfaces, like ORC or LibGCCJIT. GCC and LLVM developers spend huge effort to implement the optimizations reliably, effectively, and to work on a lot of targets. Using LLVM or GCC to implement JIT, we can just utilize these optimizations for free. Using the existing compilers was the only way to get JIT for CRuby in the short time before the Ruby 3.0 release, which has the goal of improving CRuby performance by three times.

So, CRuby MJIT utilizes GCC or LLVM, but what is unique about this JIT?

Continue reading “MIR: A lightweight JIT compiler project”

Share
Support lifecycle for Clang/LLVM, Go, and Rust in Red Hat Enterprise Linux 8

Support lifecycle for Clang/LLVM, Go, and Rust in Red Hat Enterprise Linux 8

Red Hat Enterprise Linux (RHEL) 8.1.0 includes updates to our llvm-toolset, go-toolset, and rust-toolset application streams, which provide developers with up-to-date versions of these compiler toolchains. The upstream projects for these streams move very quickly with new feature releases every six months for LLVM and Go, and every six weeks (!) for Rust. The communities around these toolchains encourage users to users to always stay up-to-date with the latest releases, which is why we try to get new versions into Red Hat Enterprise Linux as quickly as we can.

From a support perspective, we will continue to support these application streams for the entire life of RHEL 8. We will provide new features and bug fixes within the stream by updating to newer upstream releases on a regular basis. For llvm-toolset and go-toolset, you can expect stream updates every six months, and for rust-toolset you can expect updates every three months.

Continue reading “Support lifecycle for Clang/LLVM, Go, and Rust in Red Hat Enterprise Linux 8”

Share
How to debug where a function returns using LLDB from the command line

How to debug where a function returns using LLDB from the command line

I often find myself in a situation when I want to know where a function returns. There’s no need to know the return value, as this may be the same for multiple code paths (e.g., nullptr if something went wrong). It is embarrassing, but I sometimes have put fprintf(stderr, "T1"); in my code just to follow which path the execution took. Needless to say, this behavior requires manual editing and recompilation and should be avoided if possible.

Here’s a way to elegantly debug where a function returns using lldb from the command line.

Continue reading “How to debug where a function returns using LLDB from the command line”

Share
Customize the compilation process with Clang: Making compromises

Customize the compilation process with Clang: Making compromises

In this two-part series, we’re looking at the Clang compiler and various ways of customizing the compilation process. These articles are an expanded version of the presentation, called Merci le Compilo, which was given at CPPP in June.

In part one, we looked at specific options for customization. And, in this article, we’ll look at some examples of compromises and tradeoffs involved in different approaches.

Continue reading “Customize the compilation process with Clang: Making compromises”

Share
Customize the compilation process with Clang: Optimization options

Customize the compilation process with Clang: Optimization options

When using C++, developers generally aim to keep a high level of abstraction without sacrificing performance. That’s the famous motto “costless abstractions.” Yet the C++ language actually doesn’t give a lot of guarantees to developers in terms of performance. You can have the guarantee of copy-elision or compile-time evaluation, but key optimizations like inlining, unrolling, constant propagation or, dare I say, tail call elimination are subject to the goodwill of the standard’s best friend: the compiler.

This article focuses on the Clang compiler and the various flags it offers to customize the compilation process. I’ve tried to keep this from being a boring list, and it certainly is not an exhaustive one.

Continue reading “Customize the compilation process with Clang: Optimization options”

Share
2 tips to make your C++ projects compile 3 times faster

2 tips to make your C++ projects compile 3 times faster

In this article, I will demonstrate how to speed up your compilation times by distributing compilation load using a distcc server container.  Specifically, I’ll show how to set up and use containers running a distcc server to distribute the compilation load over a heterogeneous cluster of nodes (development laptop, old desktop PC, and a Mac). To improve the speed of recompilation, I will use ccache.

Continue reading “2 tips to make your C++ projects compile 3 times faster”

Share
A look at LLVM Advanced Data Types and trivially copyable types

A look at LLVM Advanced Data Types and trivially copyable types

A few bugs have been lurking in the LLVM Bugzilla for a long time, namely #39427 and #35978, which are related to a custom implementation of the is_trivially_copyable data type, and they have a bad impact on the Application Binary Interface (ABI) of LLVM libraries. In this article, I will take a closer look at these issues and describe potential workarounds.

The LLVM compiler infrastructure relies on several Advanced Data Types (ADT) to provide different speed/size trade-offs than the containers from the Standard Template Library (STL). Additionally, this ADT library provides features from future standard versions, but implemented in the C++ version (currently C++11) that LLVM supports as a code base. Finally, these ADTs must be compatible with the compiler requirements of the LLVM code base; basically, GCC version >= 4.8 and Clang version >= 3.1. (If you are interested in LLVM ADTs, Chandler Carruth did a nice talk on the subject at CppCon 2016.)

Continue reading “A look at LLVM Advanced Data Types and trivially copyable types”

Share