Skip to content
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] Make use of !invariant.group metadata for const allocas #1159

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion clang/lib/CIR/Dialect/Transforms/HoistAllocas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ static void process(cir::FuncOp func) {

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

for (auto alloca : allocas)
for (auto alloca : allocas) {
alloca->moveBefore(insertPoint);
if (alloca.getConstant()) {
// For now, we remove the const flag on nested allocas for constant
// variables when hoisting them.
alloca.setConstant(false);
}
}
}

void HoistAllocasPass::runOnOperation() {
Expand Down
17 changes: 12 additions & 5 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,8 +949,7 @@ mlir::LogicalResult CIRToLLVMVTTAddrPointOpLowering::matchAndRewrite(

if (op.getSymAddr()) {
if (op.getOffset() == 0) {
rewriter.replaceAllUsesWith(op, llvmAddr);
rewriter.eraseOp(op);
rewriter.replaceOp(op, {llvmAddr});
bcardosolopes marked this conversation as resolved.
Show resolved Hide resolved
return mlir::success();
}

Expand Down Expand Up @@ -1480,11 +1479,15 @@ mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite(
alignment = *alignOpt;
}

// TODO: nontemporal, invariant, syncscope.
auto addrAllocaOp =
mlir::dyn_cast_if_present<cir::AllocaOp>(op.getAddr().getDefiningOp());
auto invariant = addrAllocaOp && addrAllocaOp.getConstant();

// TODO: nontemporal, syncscope.
rewriter.replaceOpWithNewOp<mlir::LLVM::LoadOp>(
op, llvmTy, adaptor.getAddr(), /* alignment */ alignment,
op.getIsVolatile(), /* nontemporal */ false,
/* invariant */ false, /* invariantGroup */ false, ordering);
/* invariant */ false, /* invariantGroup */ invariant, ordering);
return mlir::LogicalResult::success();
}

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

auto addrAllocaOp =
mlir::dyn_cast_if_present<cir::AllocaOp>(op.getAddr().getDefiningOp());
auto invariant = addrAllocaOp && addrAllocaOp.getConstant();

// TODO: nontemporal, syncscope.
rewriter.replaceOpWithNewOp<mlir::LLVM::StoreOp>(
op, adaptor.getValue(), adaptor.getAddr(), alignment, op.getIsVolatile(),
/* nontemporal */ false, /* invariantGroup */ false, ordering);
/* nontemporal */ false, /* invariantGroup */ invariant, ordering);
return mlir::LogicalResult::success();
}

Expand Down
50 changes: 34 additions & 16 deletions clang/test/CIR/CodeGen/const-alloca.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
// RUN: FileCheck --input-file=%t.cir --check-prefix=CIR %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll --check-prefix=LLVM %s

int produce_int();
void blackbox(const int &);
Expand All @@ -8,33 +10,33 @@ void local_const_int() {
const int x = produce_int();
}

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

void param_const_int(const int x) {}

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

void local_constexpr_int() {
constexpr int x = 42;
blackbox(x);
}

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

void local_reference() {
int x = 0;
int &r = x;
}

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

struct Foo {
int a;
Expand All @@ -47,6 +49,22 @@ void local_const_struct() {
const Foo x = produce_foo();
}

// CHECK-LABEL: @_Z18local_const_structv
// CHECK: %{{.+}} = cir.alloca !ty_Foo, !cir.ptr<!ty_Foo>, ["x", init, const]
// CHECK: }
// CIR-LABEL: @_Z18local_const_structv
// CIR: %{{.+}} = cir.alloca !ty_Foo, !cir.ptr<!ty_Foo>, ["x", init, const]
// CIR: }

int local_const_load_store() {
const int x = produce_int();
int y = x;
return y;
}

// CIR-LABEL: @_Z22local_const_load_storev
// CIR: %{{.+}} = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init, const] {alignment = 4 : i64}
// CIR: }

// LLVM-LABEL: @_Z22local_const_load_storev
// LLVM: %[[#INIT:]] = call i32 @_Z11produce_intv()
// LLVM-NEXT: store i32 %[[#INIT]], ptr %[[#SLOT:]], align 4, !dbg !{{.+}}, !invariant.group !{{.+}}
// LLVM-NEXT: %{{.+}} = load i32, ptr %[[#SLOT]], align 4, !dbg !{{.+}}, !invariant.group !{{.+}}
// LLVM: }