-
Notifications
You must be signed in to change notification settings - Fork 141
[CIR][Lowering] Add the concept of simple lowering and use it to implement FP intrincis #434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Global addresses are constant, so we can initialize them at compile time using CIR's global_view attribute. This patch adds codegen support for the initialization of variables with constant global addresses. Since a builder method was added for global_view, the patch also updates the codegen of global variables to use it wherever possible. ghstack-source-id: 513365c Pull Request resolved: llvm#204
Adds lowering logic for CIR's global_view attributes with no indexes. This is done by converting the global to a region-initialized LLVM global operation, where the region returns the address of the global used in the gloval_view initializer attribute. ghstack-source-id: a9452ed Pull Request resolved: llvm#205
Constant initialization of static local arrays would fail due to a mismatch between the variable and the initializer type size. This patch fixes the data layout interface implementation for the cir.array type. A complete array in C/C++ should have its type size in bits equal to the size of the array times the size of the element type. ghstack-source-id: 56f3f29 Pull Request resolved: llvm#206
…es instead of region initializers.
PR llvm#200 broke the vtableAttr usage, as it was not properly refactored to use ArrayAttr instead of ConstStructAttr to store its members.
This change does the CIR generation for globals initialized by a constructor call. It currently only covers C++ to CIR generation. The corresponding LLVM lowering will be in a follow-up commit. A motivating example is ``` class Init { friend class ios_base; public: Init(bool); ~Init(); private: static bool _S_synced_with_stdio; }; static Init ioinit(true); ``` Unlike what the default Clang codegen generates LLVM that detaches the initialization code from the global var definition (like below), we are taking a different approach that keeps them together, which we think will make the later dataflow analysis/transform easier. ``` @_ZL8ioinit = internal global %class.Init zeroinitializer, align 1, !dbg !0 define internal void @cxx_global_var_init() #0 section ".text.startup" !dbg !23 { entry: call void @_ZN4InitC2Ev(ptr noundef nonnull align 1 dereferenceable(1) @_ZL8ioinit), !dbg !27 %0 = call i32 @cxa_atexit(ptr @_ZN4InitD1Ev, ptr @_ZL8ioinit, ptr @dso_handle) llvm#3, !dbg !29 ret void, !dbg !27 } ``` So on CIR, we have something like: ``` cir.global "private" internal @_ZL8__ioinit = ctor : !ty_22class2EInit22 { %0 = cir.get_global @_ZL8__ioinit : cir.ptr <!ty_22class2EInit22> loc(#loc8) %1 = cir.const(#true) : !cir.bool loc(#loc5) cir.call @_ZN4InitC1Eb(%0, %1) : (!cir.ptr<!ty_22class2EInit22>, !cir.bool) -> () loc(#loc6) } ``` The destructor support will also be in a separate change.
This PR fixes lowering for `break/continue` in loops. The idea is to replace `cir.yield break` and `cir.yield continue` with the branch operations to the corresponding blocks. Note, that we need to ignore nesting loops and don't touch `break` in switch operations. Also, `yield` from `if` need to be considered only when it's not the loop `yield` and `continue` in switch is ignored since it's processed in the loops lowering. Fixes llvm#160
…cations are the same
Essentially emits an LValue for the struct and then passes it as a call argument.
Enabling IR printing with --mlir-print-ir-after=passName1, passName2. This requires all CIR passes to be registered at startup time.
Summary: Setting the Optnone attribute for CIR functions and progating it all the way down to LLVM IR for those not supposed to be optimized.
This change is a prerequisite of llvm#235
…zers (llvm#235) As a follow up to llvm#197, this change pre-lowers high-level CIR for global initializers. High-level CIR: ``` cir.global "private" internal @_ZL8__ioinit = ctor : !ty_22class2EInit22 { %0 = cir.get_global @_ZL8__ioinit : cir.ptr <!ty_22class2EInit22> loc(#loc8) %1 = cir.const(#true) : !cir.bool loc(#loc5) cir.call @_ZN4InitC1Eb(%0, %1) : (!cir.ptr<!ty_22class2EInit22>, !cir.bool) -> () loc(#loc6) } ``` After pre-lowering: ``` cir.global "private" internal @_ZL8__ioinit = #cir.zero : !ty_22class2EInit22 {ast = #cir.vardecl.ast} cir.func internal private @__cxx_global_var_init() { %0 = cir.get_global @_ZL8__ioinit : cir.ptr <!ty_22class2EInit22> %1 = cir.const(#true) : !cir.bool cir.call @_ZN4InitC1Eb(%0, %1) : (!cir.ptr<!ty_22class2EInit22>, !cir.bool) -> () cir.return } cir.func private @_GLOBAL__sub_I_static.cpp() { cir.call @__cxx_global_var_init() : () -> () cir.return } ``` There is still work to be done to fully lower to LLVM. E.g, add `llvm.global_ctors` global to list all module initializers like `_GLOBAL__sub_I_static`. This will be handled in a separate change.
cir-tidy has been our custom hack for using clang-tidy. There's no reason it needs to be that way - add a CIRModule to clang-tidy and make the lifetime checker its first check. Some of the way this was built was inspired in CLANG_TIDY_ENABLE_STATIC_ANALYZER Once we can fully migrate deps from cir-tidy, we should remove it in favor of this.
…s::options This unbreaks Linux builds, which points to cycles while using utils::options from ClangTidy.cpp. We need to find a better way to convey this.
This PR fixes CIR generation for the `switch-case` cases like the following: ``` case 'a': default: ... ``` or ``` default: case 'a': ... ``` i.e. when the `default` clause is sub-statement of the `case` one and vice versa.
Whenever a global array is declared and initialized with fewer elements than its size, the remaining elements are implicitly initialized with zero. For aggregates types, such as structs, the initialization is done through the #cir.zero attribute. ghstack-source-id: b3d172c Pull Request resolved: llvm#216
Due to the lack of zeroinitializer support in LLVM, some cases are tricky to lower #cir.zero. An example is when an array is only partially initialize with #cir.zero attributes. Since we can't just zeroinitialize the whole array, the current #cir.zero attribute amend does not suffice. To simplify the lowering, this patch introduces a new operation that is solely used to generate zeroinitialize LLVM IR constants. ghstack-source-id: a3fd40e Pull Request resolved: llvm#218
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really nice, yay! Mostly cosmetic changes needed.
@@ -1797,6 +1802,9 @@ def VecInsertOp : CIR_Op<"vec.insert", [Pure, | |||
}]; | |||
|
|||
let hasVerifier = 0; | |||
|
|||
let SimpleLowering = 1; | |||
let LLVMOpName = "InsertElementOp"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dkolsen-pgi do you plan to change these ops soon in any way that would invalidate this approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have any plans to change cir.vec.insert
or cir.vec.extract
. I am fine with simplifying the LLVM lowering.
@@ -36,8 +36,13 @@ include "mlir/IR/SymbolInterfaces.td" | |||
// CIR Ops | |||
//===----------------------------------------------------------------------===// | |||
|
|||
class LoweringInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment explaining what's the purpose of this class.
@@ -36,8 +36,13 @@ include "mlir/IR/SymbolInterfaces.td" | |||
// CIR Ops | |||
//===----------------------------------------------------------------------===// | |||
|
|||
class LoweringInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you plan to use this for things other than facilitating LLVM lowering? If not, I suggest you rename this to LLVMLoweringInfo
for now.
@@ -36,8 +36,13 @@ include "mlir/IR/SymbolInterfaces.td" | |||
// CIR Ops | |||
//===----------------------------------------------------------------------===// | |||
|
|||
class LoweringInfo { | |||
bit SimpleLowering = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this SimpleLowering
as opposed to which other types of lowering? My suggestion is to tie it up for now with the only implemented thing, which is builtins: bit builtinLowering = 0
;
@@ -36,8 +36,13 @@ include "mlir/IR/SymbolInterfaces.td" | |||
// CIR Ops | |||
//===----------------------------------------------------------------------===// | |||
|
|||
class LoweringInfo { | |||
bit SimpleLowering = 0; | |||
string LLVMOpName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's lowercase all member to be a closer match to MLIR, so this one would be llvmOpName
;
This is an awesome feature! This is not a blocker for the PR, just some ideas for further development. This feature may be generalized in the future to declare lowering rules more flexibly. Consider the %1 = cir.bit.clz(%0 : !u32i) : !s32i
// %1 = llvm.call_intrinsic "llvm.ctlz.i32"(%0 : i32) : i32 -> i32
%2 = cir.bit.ctz(%0 : !u32i) : !s32i
// %2 = llvm.call_intrinsic "llvm.cttz.i32"(%0 : i32) : i32 -> i32
%3 = cir.bit.popcount(%0 : !u32i) : !s32i
// %3 = llvm.call_intrinsic "llvm.ctpop.i32"(%0 : i32) : i32 -> i32 Basically all Stuff in this PR cannot be used to achieve the lowering scheme above because we cannot specify the parameters to the LLVMIR operations. It would be nice if this is added in the future; it would be very useful for lowering compiler intrinsics as shown above. |
Good point @Lancern, we can definitely extend the mechanism later to also support things that get lowered to |
ed3955a
to
8b7417c
Compare
c4db6d0
to
e197d4e
Compare
Any progress on this PR? |
@philnik777 is probably busy with libc++ work. @Lancern if you are interested in making progress here, my suggestion:
I'll then land without squashing so that we can preserve your work and his (assuming we get a final total of 2 commits, his + yours). |
Sorry for dropping this. I completely forgot that I had a patch open here. @Lancern if you want to, feel free to take the patch and just add a |
Let me work on this PR. |
@philnik777 np, thanks for the clangir contribs so far! |
This is now tracked in #806, closing |
…ry fp2fp operations (#806) This PR is the continuation and refinement of PR #434 which is originally authored by @philnik777 . Does not update it in-place since I don't have commit access to Nikolas' repo. This PR basically just rebases #434 onto the latest `main`. I also updated some naming used in the original PR to keep naming styles consistent. Co-authored-by: Nikolas Klauser <[email protected]>
…ry fp2fp operations (llvm#806) This PR is the continuation and refinement of PR llvm#434 which is originally authored by @philnik777 . Does not update it in-place since I don't have commit access to Nikolas' repo. This PR basically just rebases llvm#434 onto the latest `main`. I also updated some naming used in the original PR to keep naming styles consistent. Co-authored-by: Nikolas Klauser <[email protected]>
…ry fp2fp operations (llvm#806) This PR is the continuation and refinement of PR llvm#434 which is originally authored by @philnik777 . Does not update it in-place since I don't have commit access to Nikolas' repo. This PR basically just rebases llvm#434 onto the latest `main`. I also updated some naming used in the original PR to keep naming styles consistent. Co-authored-by: Nikolas Klauser <[email protected]>
…ry fp2fp operations (llvm#806) This PR is the continuation and refinement of PR llvm#434 which is originally authored by @philnik777 . Does not update it in-place since I don't have commit access to Nikolas' repo. This PR basically just rebases llvm#434 onto the latest `main`. I also updated some naming used in the original PR to keep naming styles consistent. Co-authored-by: Nikolas Klauser <[email protected]>
…ry fp2fp operations (llvm#806) This PR is the continuation and refinement of PR llvm#434 which is originally authored by @philnik777 . Does not update it in-place since I don't have commit access to Nikolas' repo. This PR basically just rebases llvm#434 onto the latest `main`. I also updated some naming used in the original PR to keep naming styles consistent. Co-authored-by: Nikolas Klauser <[email protected]>
…ry fp2fp operations (#806) This PR is the continuation and refinement of PR #434 which is originally authored by @philnik777 . Does not update it in-place since I don't have commit access to Nikolas' repo. This PR basically just rebases #434 onto the latest `main`. I also updated some naming used in the original PR to keep naming styles consistent. Co-authored-by: Nikolas Klauser <[email protected]>
…ry fp2fp operations (#806) This PR is the continuation and refinement of PR #434 which is originally authored by @philnik777 . Does not update it in-place since I don't have commit access to Nikolas' repo. This PR basically just rebases #434 onto the latest `main`. I also updated some naming used in the original PR to keep naming styles consistent. Co-authored-by: Nikolas Klauser <[email protected]>
No description provided.