Skip to content

Commit 2ae7176

Browse files
committed
[CIR] Make use of !invariant.group metadata for const allocas
This patch updates the LLVM lowering part of load and stores to const allocas and makes use of the !invariant.group metadata in the result LLVM IR. The HoistAlloca pass is also updated. The const flag on a hoisted alloca is removed for now since their uses are not always invariants. Will update in later patches to teach their invariants.
1 parent 41078e9 commit 2ae7176

File tree

3 files changed

+53
-22
lines changed

3 files changed

+53
-22
lines changed

clang/lib/CIR/Dialect/Transforms/HoistAllocas.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,14 @@ static void process(cir::FuncOp func) {
4848

4949
mlir::Operation *insertPoint = &*entryBlock.begin();
5050

51-
for (auto alloca : allocas)
51+
for (auto alloca : allocas) {
5252
alloca->moveBefore(insertPoint);
53+
if (alloca.getConstant()) {
54+
// For now, we remove the const flag on nested allocas for constant
55+
// variables when hoisting them.
56+
alloca.setConstant(false);
57+
}
58+
}
5359
}
5460

5561
void HoistAllocasPass::runOnOperation() {

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

+12-5
Original file line numberDiff line numberDiff line change
@@ -949,8 +949,7 @@ mlir::LogicalResult CIRToLLVMVTTAddrPointOpLowering::matchAndRewrite(
949949

950950
if (op.getSymAddr()) {
951951
if (op.getOffset() == 0) {
952-
rewriter.replaceAllUsesWith(op, llvmAddr);
953-
rewriter.eraseOp(op);
952+
rewriter.replaceOp(op, {llvmAddr});
954953
return mlir::success();
955954
}
956955

@@ -1480,11 +1479,15 @@ mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite(
14801479
alignment = *alignOpt;
14811480
}
14821481

1483-
// TODO: nontemporal, invariant, syncscope.
1482+
auto addrAllocaOp =
1483+
mlir::dyn_cast_if_present<cir::AllocaOp>(op.getAddr().getDefiningOp());
1484+
auto invariant = addrAllocaOp && addrAllocaOp.getConstant();
1485+
1486+
// TODO: nontemporal, syncscope.
14841487
rewriter.replaceOpWithNewOp<mlir::LLVM::LoadOp>(
14851488
op, llvmTy, adaptor.getAddr(), /* alignment */ alignment,
14861489
op.getIsVolatile(), /* nontemporal */ false,
1487-
/* invariant */ false, /* invariantGroup */ false, ordering);
1490+
/* invariant */ false, /* invariantGroup */ invariant, ordering);
14881491
return mlir::LogicalResult::success();
14891492
}
14901493

@@ -1505,10 +1508,14 @@ mlir::LogicalResult CIRToLLVMStoreOpLowering::matchAndRewrite(
15051508
alignment = *alignOpt;
15061509
}
15071510

1511+
auto addrAllocaOp =
1512+
mlir::dyn_cast_if_present<cir::AllocaOp>(op.getAddr().getDefiningOp());
1513+
auto invariant = addrAllocaOp && addrAllocaOp.getConstant();
1514+
15081515
// TODO: nontemporal, syncscope.
15091516
rewriter.replaceOpWithNewOp<mlir::LLVM::StoreOp>(
15101517
op, adaptor.getValue(), adaptor.getAddr(), alignment, op.getIsVolatile(),
1511-
/* nontemporal */ false, /* invariantGroup */ false, ordering);
1518+
/* nontemporal */ false, /* invariantGroup */ invariant, ordering);
15121519
return mlir::LogicalResult::success();
15131520
}
15141521

+34-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2-
// RUN: FileCheck --input-file=%t.cir %s
2+
// RUN: FileCheck --input-file=%t.cir --check-prefix=CIR %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --input-file=%t.ll --check-prefix=LLVM %s
35

46
int produce_int();
57
void blackbox(const int &);
@@ -8,33 +10,33 @@ void local_const_int() {
810
const int x = produce_int();
911
}
1012

11-
// CHECK-LABEL: @_Z15local_const_intv
12-
// CHECK: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init, const]
13-
// CHECK: }
13+
// CIR-LABEL: @_Z15local_const_intv
14+
// CIR: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init, const]
15+
// CIR: }
1416

1517
void param_const_int(const int x) {}
1618

17-
// CHECK-LABEL: @_Z15param_const_inti
18-
// CHECK: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init, const]
19-
// CHECK: }
19+
// CIR-LABEL: @_Z15param_const_inti
20+
// CIR: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init, const]
21+
// CIR: }
2022

2123
void local_constexpr_int() {
2224
constexpr int x = 42;
2325
blackbox(x);
2426
}
2527

26-
// CHECK-LABEL: @_Z19local_constexpr_intv
27-
// CHECK: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init, const]
28-
// CHECK: }
28+
// CIR-LABEL: @_Z19local_constexpr_intv
29+
// CIR: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init, const]
30+
// CIR: }
2931

3032
void local_reference() {
3133
int x = 0;
3234
int &r = x;
3335
}
3436

35-
// CHECK-LABEL: @_Z15local_referencev
36-
// CHECK: %{{.+}} = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["r", init, const]
37-
// CHECK: }
37+
// CIR-LABEL: @_Z15local_referencev
38+
// CIR: %{{.+}} = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["r", init, const]
39+
// CIR: }
3840

3941
struct Foo {
4042
int a;
@@ -47,6 +49,22 @@ void local_const_struct() {
4749
const Foo x = produce_foo();
4850
}
4951

50-
// CHECK-LABEL: @_Z18local_const_structv
51-
// CHECK: %{{.+}} = cir.alloca !ty_Foo, !cir.ptr<!ty_Foo>, ["x", init, const]
52-
// CHECK: }
52+
// CIR-LABEL: @_Z18local_const_structv
53+
// CIR: %{{.+}} = cir.alloca !ty_Foo, !cir.ptr<!ty_Foo>, ["x", init, const]
54+
// CIR: }
55+
56+
int local_const_load_store() {
57+
const int x = produce_int();
58+
int y = x;
59+
return y;
60+
}
61+
62+
// CIR-LABEL: @_Z22local_const_load_storev
63+
// CIR: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init, const] {alignment = 4 : i64}
64+
// CIR: }
65+
66+
// LLVM-LABEL: @_Z22local_const_load_storev
67+
// LLVM: %[[#INIT:]] = call i32 @_Z11produce_intv()
68+
// LLVM-NEXT: store i32 %[[#INIT]], ptr %[[#SLOT:]], align 4, !dbg !{{.+}}, !invariant.group !{{.+}}
69+
// LLVM-NEXT: %{{.+}} = load i32, ptr %[[#SLOT]], align 4, !dbg !{{.+}}, !invariant.group !{{.+}}
70+
// LLVM: }

0 commit comments

Comments
 (0)