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
[CIR][Lowering] Add the concept of simple lowering and use it to implement FP intrincis #434
base: main
Are you sure you want to change the base?
Conversation
Lowers the particular case where an array of structs is constant-initialized. ghstack-source-id: f8389d899e07f73485658d86469d7595a4373901 Pull Request resolved: llvm#202
Updates the lowering of cir.const to support #cir.const_struct as a initializer, allowing the initialization of local structs with said attribute. ghstack-source-id: cc6c1378775bd2239c821c357e281bbc8cc3b0a7 Pull Request resolved: llvm#203
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: 513365c52ac1ca603a81fcf3ff124b5da39f6f14 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: a9452eddbd516553273461a8187afcebc211e4d3 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: 56f3f2918b23309210ad026017bafa37ca03b2d4 Pull Request resolved: llvm#206
ghstack-source-id: 1f793b2abcb144ab10b1ddbd99f12d1dcc6c8707 Pull Request resolved: llvm#207
…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: b3d172c8092acf904f9c2204621d900d70d0e819 Pull Request resolved: llvm#216
This small improvement allows for a more compact representation of structs with zero-initialized fields in the C++ codegen. ghstack-source-id: a3fe0dc6c0dd89e22cb38167bb9d9cd7b9f43b8f Pull Request resolved: llvm#217
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: a3fd40ec3ce8970ac4e958076cc17d3fac573696 Pull Request resolved: llvm#218
Supports lowering for #cir.zero attributes when it appears in aggregate attributes such as #const.array and #cir.struct. ghstack-source-id: d26a506f29b581ed57d838e5281d9abbb2c24820 Pull Request resolved: llvm#219
Creates a separate C/C++ operation for do-while loops, while keeping the LoopOpInterface to generically handle loops. This simplifies the IR generation and printing/parsing of do-while loops. It also allows us to define it regions in the order that they are executed, which is useful for the lifetime analysis. ghstack-source-id: b4d9517197b8f82ae677dc2684101fe5762b21b7 Pull Request resolved: llvm#407
Creates a separate C/C++ operation for while loops, while keeping the LoopOpInterface to generically handle loops. This simplifies the IR generation and printing/parsing of while loops. ghstack-source-id: 29a6d7530263a4f96dbe6ce3052875831126005d Pull Request resolved: llvm#408
This patch completes the deprecation of the generic `cir.loop` operation by adding a new `cir.for` operation and removing the `cir.loop` op. The new representation removes some bloat and places the regions in order of execution. ghstack-source-id: 886e0dacc632e5809015e2212810d690ef3ec294 Pull Request resolved: llvm#409
…rations More machinery for exceptions. This time around we finally emit a cir.catch and fix the order of emitting operations. This allows a testcase to be added. I also added `CatchParamOp`, which fetches the arguments for the clauses from the !cir.eh_info object. Work coming next: - Dtors. - Use cir.try instead of cir.scope. - Eesume. - Documentation.`
This is currently missing and Debug builds are failing without it.
ghstack-source-id: 855519648a4bf2dced501f96e6de1b9b164d85ad Pull Request resolved: llvm#424
ghstack-source-id: 0706d6bb81b5b8eefb04146719b4443aedb29ab1 Pull Request resolved: llvm#427
One more step towards completing try/catch.
…rface This is prep work for introducing cir.try_call inside cir.try scopes.
One more incremental step towards try/catch: properly use cir.try_call instead of regular cir.call when within a cir.try region.
) This patch adds a new `volatile` tag to the following operations to distinguish volatile loads and stores from normal loads and stores: - `cir.load` - `cir.store` - `cir.get_bitfield` - `cir.set_bitfield` Besides, this patch also updates the CodeGen and LLVMIR lowering code to start emitting CIR and LLVMIR operations with volatile flag.
This is part 3 of implementing vector types and vector operations in ClangIR, issue llvm#284. Create new operation `cir.vec.cmp` which implements the relational comparison operators (`== != < > <= >=`) on vector types. A new operation was created rather than reusing `cir.cmp` because the result is a vector of a signed intergral type, not a `bool`. Add CodeGen and Lowering tests for vector comparisons. Fix the floating-point comparison predicate when lowering to LLVM. To handle NaN values correctly, the comparisons need to be ordered rather than unordered. (Except for `!=`, which needs to be unordered.) For example, "ueq" was changed to "oeq".
Compilation of the following test ``` void foo6(A* a1) { A a2 = (*a1); } ``` fails with. ``` NYI UNREACHABLE executed at /home/huawei/cir/repo/llvm-project/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp:175! ``` Commit adds required visitor and fixes the issue.
…ment FP intrincis
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
No description provided.