forked from llvm/clangir
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CIR][CIRGen][Lowering] Add support for attribute annotate (llvm#804)
The main purpose of this PR is to add support for C/C++ attribute annotate. The PR involves both CIR generation and Lowering Prepare. In the rest of this description, we first introduce the concept of attribute annotate, then talk about expectations of LLVM regarding annotation, after it, we describe how ClangIR handles it in this PR. Finally, we list trivial differences between LLVM code generated by clang codegen and ClangIR codegen. **The concept of attribute annotate. and expected LLVM IR** the following is C code example of annotation. say in example.c `int *b __attribute__((annotate("withargs", "21", 12 ))); int *a __attribute__((annotate("oneargs", "21", ))); int *c __attribute__((annotate("noargs"))); ` here "withargs" is the annotation string, "21" and 12 are arguments for this annotation named "withargs". LLVM-based compiler is expected keep these information and build a global variable capturing all annotations used in the translation unit when emitting into LLVM IR. This global variable itself is **not** constant, but will be initialized with constants that are related to annotation representation, e.g. "withargs" should be literal string variable in IR. This global variable has a fixed name "llvm.global.annotations", and its of array of struct type, and should be initialized with a const array of const structs, each const struct is a representation of an annotation site, which has 5-field. [ptr to global var/func annotated, ptr to translation unit string const, line_no, annotation_name, ptr to arguments const] annotation name string and args constants, as well as this global var should be in section "llvm.metadata". e.g. In the above example, We shall have following in the generated LLVM IR like the following ``` @b = global ptr null, align 8 @.str = private unnamed_addr constant [9 x i8] c"withargs\00", section "llvm.metadata" @.str.1 = private unnamed_addr constant [10 x i8] c"example.c\00", section "llvm.metadata" @.str.2 = private unnamed_addr constant [3 x i8] c"21\00", align 1 @.args = private unnamed_addr constant { ptr, i32 } { ptr @.str.2, i32 12 }, section "llvm.metadata" @A = global ptr null, align 8 @.str.3 = private unnamed_addr constant [8 x i8] c"oneargs\00", section "llvm.metadata" @.args.4 = private unnamed_addr constant { ptr } { ptr @.str.2 }, section "llvm.metadata" @c = global ptr null, align 8 @.str.5 = private unnamed_addr constant [7 x i8] c"noargs\00", section "llvm.metadata" @llvm.global.annotations = appending global [3 x { ptr, ptr, ptr, i32, ptr }] [{ ptr, ptr, ptr, i32, ptr } { ptr @b, ptr @.str, ptr @.str.1, i32 1, ptr @.args }, { ptr, ptr, ptr, i32, ptr } { ptr @A, ptr @.str.3, ptr @.str.1, i32 2, ptr @.args.4 }, { ptr, ptr, ptr, i32, ptr } { ptr @c, ptr @.str.5, ptr @.str.1, i32 3, ptr null }], section "llvm.metadata" ``` notice that since variable c's annotation has no arg, the last field of its corresponding annotation entry is a nullptr. **ClangIR's handling of annotations** In CIR, we introduce AnnotationAttr to GlobalOp and FuncOp to record its annotations. That way, we are able to make fast query about annotation if in future a CIR pass is interested in them. We leave the work of generating const variables as well as global annotations' var to LLVM lowering. But at LoweringPrepare we collect all annotations and create a module attribute "cir.global_annotations" so to facilitate LLVM lowering. **Some implementation details and trivial differences between clangir generated LLVM code and vanilla LLVM code** 1. I suffix names of constants generated for annotation purpose with ".annotation" to avoid redefinition, but clang codegen doesn't do it. 3. clang codegen seems to visit FuncDecls in slightly different orders than CIR, thus, sometimes the order of elements of the initial value const array for llvm.global.annotations var is different from clang generated LLVMIR, it should be trivial, as I don't expect consumer of this var is assuming a fixed order of collecting annotations. Otherwise, clang codegen and clangir pretty much generate same LLVM IR for annotations!
- Loading branch information
Showing
11 changed files
with
654 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.