Skip to content

Commit 48a2570

Browse files
[CIR] Add BlockAddrInfoAttr for LabelOp and BlockAddressOp (#1918)
This PR adds the new attribute `CIR_BlockAddrInfoAttr`, requested in [#1909](#1909), which is used in `BlockAddressOp` and `LabelOp`. I also created a custom builder to simplify construction so that we don’t have to call `mlir::FlatSymbolRefAttr::get` and `mlir::StringAttr::get` every time.
1 parent 6ce3969 commit 48a2570

File tree

11 files changed

+71
-54
lines changed

11 files changed

+71
-54
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,31 @@ def CIR_AddressPointAttr : CIR_Attr<"AddressPoint", "address_point"> {
15061506
}];
15071507
}
15081508

1509+
//===----------------------------------------------------------------------===//
1510+
// CIR_BlockAddrInfoAttr
1511+
//===----------------------------------------------------------------------===//
1512+
1513+
def CIR_BlockAddrInfoAttr : CIR_Attr<"BlockAddrInfo", "block_addr_info"> {
1514+
let summary = "Block Addres attribute";
1515+
let description = [{
1516+
This attribute is used to represent the address of a basic block
1517+
within a function. It combines the symbol reference to a function
1518+
with the name of a label inside that function.
1519+
}];
1520+
let parameters = (ins "mlir::FlatSymbolRefAttr":$func,
1521+
"mlir::StringAttr":$label);
1522+
1523+
let assemblyFormat = "`<` $func `,` $label `>`";
1524+
let builders = [
1525+
AttrBuilder<(ins "llvm::StringRef":$func_name,
1526+
"llvm::StringRef":$label_name
1527+
), [{
1528+
return $_get($_ctxt, mlir::FlatSymbolRefAttr::get($_ctxt, func_name),
1529+
mlir::StringAttr::get($_ctxt, label_name));
1530+
}]>
1531+
];
1532+
}
1533+
15091534
include "clang/CIR/Dialect/IR/CIRTBAAAttrs.td"
15101535

15111536
include "clang/CIR/Dialect/IR/CIROpenCLAttrs.td"

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6144,10 +6144,10 @@ def CIR_BlockAddressOp : CIR_Op<"blockaddress", [Pure]> {
61446144
```
61456145
}];
61466146

6147-
let arguments = (ins FlatSymbolRefAttr:$func, StrAttr:$label);
6147+
let arguments = (ins CIR_BlockAddrInfoAttr:$blockAddrInfo);
61486148
let results = (outs CIR_VoidPtrType:$addr);
61496149
let assemblyFormat = [{
6150-
`(` $func `,` $label `)` `->` qualified(type($addr)) attr-dict
6150+
$blockAddrInfo `->` qualified(type($addr)) attr-dict
61516151
}];
61526152
}
61536153

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -229,15 +229,11 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
229229

230230
mlir::Value VisitAddrLabelExpr(const AddrLabelExpr *e) {
231231
auto func = cast<cir::FuncOp>(CGF.CurFn);
232-
llvm::StringRef symName = func.getSymName();
233-
mlir::FlatSymbolRefAttr funName =
234-
mlir::FlatSymbolRefAttr::get(&CGF.getMLIRContext(), symName);
235-
mlir::StringAttr labelName =
236-
mlir::StringAttr::get(&CGF.getMLIRContext(), e->getLabel()->getName());
232+
auto blockInfoAttr = cir::BlockAddrInfoAttr::get(
233+
&CGF.getMLIRContext(), func.getSymName(), e->getLabel()->getName());
237234
return cir::BlockAddressOp::create(Builder, CGF.getLoc(e->getSourceRange()),
238-
CGF.convertType(e->getType()), funName,
239-
labelName);
240-
;
235+
CGF.convertType(e->getType()),
236+
blockInfoAttr);
241237
}
242238
mlir::Value VisitSizeOfPackExpr(SizeOfPackExpr *E) {
243239
llvm_unreachable("NYI");

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,12 +2939,12 @@ LogicalResult cir::FuncOp::verify() {
29392939
} else if (auto goTo = dyn_cast<cir::GotoOp>(op)) {
29402940
gotos.insert(goTo.getLabel());
29412941
} else if (auto blkAdd = dyn_cast<cir::BlockAddressOp>(op)) {
2942-
if (blkAdd.getFunc() != getSymName()) {
2942+
if (blkAdd.getBlockAddrInfoAttr().getFunc().getAttr() != getSymName()) {
29432943
// Stop the walk early, no need to continue
29442944
invalidBlockAddress = true;
29452945
return mlir::WalkResult::interrupt();
29462946
}
2947-
blockAddresses.insert(blkAdd.getLabel());
2947+
blockAddresses.insert(blkAdd.getBlockAddrInfoAttr().getLabel());
29482948
}
29492949
return mlir::WalkResult::advance();
29502950
});

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static void process(cir::FuncOp func) {
3333
} else if (auto goTo = dyn_cast<cir::GotoOp>(op)) {
3434
gotos.push_back(goTo);
3535
} else if (auto blockAddr = dyn_cast<cir::BlockAddressOp>(op)) {
36-
blockAddrLabel.insert(blockAddr.getLabel());
36+
blockAddrLabel.insert(blockAddr.getBlockAddrInfo().getLabel());
3737
}
3838
});
3939

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4518,7 +4518,9 @@ mlir::LogicalResult CIRToLLVMLabelOpLowering::matchAndRewrite(
45184518
auto blockTagOp =
45194519
mlir::LLVM::BlockTagOp::create(rewriter, op->getLoc(), tagAttr);
45204520
auto func = op->getParentOfType<mlir::LLVM::LLVMFuncOp>();
4521-
blockInfoAddr.mapBlockTag(func.getSymName(), op.getLabel(), blockTagOp);
4521+
auto blockInfoAttr =
4522+
cir::BlockAddrInfoAttr::get(ctx, func.getSymName(), op.getLabel());
4523+
blockInfoAddr.mapBlockTag(blockInfoAttr, blockTagOp);
45224524
rewriter.eraseOp(op);
45234525

45244526
return mlir::success();
@@ -4530,7 +4532,7 @@ mlir::LogicalResult CIRToLLVMBlockAddressOpLowering::matchAndRewrite(
45304532
mlir::MLIRContext *ctx = rewriter.getContext();
45314533

45324534
mlir::LLVM::BlockTagOp matchLabel =
4533-
blockInfoAddr.lookupBlockTag(op.getFunc(), op.getLabel());
4535+
blockInfoAddr.lookupBlockTag(op.getBlockAddrInfoAttr());
45344536
mlir::LLVM::BlockTagAttr tagAttr;
45354537
if (!matchLabel)
45364538
// If the BlockTagOp has not been emitted yet, use a placeholder.
@@ -4540,13 +4542,13 @@ mlir::LogicalResult CIRToLLVMBlockAddressOpLowering::matchAndRewrite(
45404542
else
45414543
tagAttr = matchLabel.getTag();
45424544

4543-
auto blkAddr = mlir::LLVM::BlockAddressAttr::get(rewriter.getContext(),
4544-
op.getFuncAttr(), tagAttr);
4545+
auto blkAddr = mlir::LLVM::BlockAddressAttr::get(
4546+
rewriter.getContext(), op.getBlockAddrInfoAttr().getFunc(), tagAttr);
45454547
rewriter.setInsertionPoint(op);
45464548
auto newOp = mlir::LLVM::BlockAddressOp::create(
45474549
rewriter, op.getLoc(), mlir::LLVM::LLVMPointerType::get(ctx), blkAddr);
45484550
if (!matchLabel)
4549-
blockInfoAddr.addUnresolvedBlockAddress(newOp, op.getFunc(), op.getLabel());
4551+
blockInfoAddr.addUnresolvedBlockAddress(newOp, op.getBlockAddrInfoAttr());
45504552
rewriter.replaceOp(op, newOp);
45514553
return mlir::success();
45524554
}
@@ -5058,10 +5060,9 @@ void ConvertCIRToLLVMPass::resolveBlockAddressOp(
50585060
for (auto &[blockAddOp, blockInfo] :
50595061
blockInfoAddr.getUnresolvedBlockAddress()) {
50605062
mlir::LLVM::BlockTagOp resolvedLabel =
5061-
blockInfoAddr.lookupBlockTag(blockInfo.first, blockInfo.second);
5063+
blockInfoAddr.lookupBlockTag(blockInfo);
50625064
assert(resolvedLabel && "expected BlockTagOp to already be emitted");
5063-
auto fnSym =
5064-
mlir::FlatSymbolRefAttr::get(module.getContext(), blockInfo.first);
5065+
auto fnSym = blockInfo.getFunc();
50655066
auto blkAddTag = mlir::LLVM::BlockAddressAttr::get(
50665067
opBuilder.getContext(), fnSym, resolvedLabel.getTagAttr());
50675068
blockAddOp.setBlockAddrAttr(blkAddTag);

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

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,45 +49,40 @@ struct LLVMBlockAddressInfo {
4949
// Get the next tag index
5050
uint32_t getTagIndex() { return blockTagOpIndex++; }
5151

52-
void mapBlockTag(llvm::StringRef func, llvm::StringRef label,
53-
mlir::LLVM::BlockTagOp tagOp) {
54-
auto result = blockInfoToTagOp.try_emplace({func, label}, tagOp);
52+
void mapBlockTag(cir::BlockAddrInfoAttr info, mlir::LLVM::BlockTagOp tagOp) {
53+
auto result = blockInfoToTagOp.try_emplace(info, tagOp);
5554
assert(result.second &&
5655
"attempting to map a BlockTag operation that is already mapped");
5756
}
5857

5958
// Lookup a BlockTagOp, may return nullptr if not yet registered.
60-
mlir::LLVM::BlockTagOp lookupBlockTag(llvm::StringRef func,
61-
llvm::StringRef label) const {
62-
return blockInfoToTagOp.lookup({func, label});
59+
mlir::LLVM::BlockTagOp lookupBlockTag(cir::BlockAddrInfoAttr info) const {
60+
return blockInfoToTagOp.lookup(info);
6361
}
6462

6563
// Record an unresolved BlockAddressOp that needs patching later.
6664
void addUnresolvedBlockAddress(mlir::LLVM::BlockAddressOp op,
67-
llvm::StringRef func, llvm::StringRef label) {
68-
unresolvedBlockAddressOp.try_emplace(op, std::make_pair(func, label));
65+
cir::BlockAddrInfoAttr info) {
66+
unresolvedBlockAddressOp.try_emplace(op, info);
6967
}
7068

7169
void clearUnresolvedMap() { unresolvedBlockAddressOp.clear(); }
7270

73-
llvm::DenseMap<mlir::LLVM::BlockAddressOp,
74-
std::pair<llvm::StringRef, llvm::StringRef>> &
71+
llvm::DenseMap<mlir::LLVM::BlockAddressOp, cir::BlockAddrInfoAttr> &
7572
getUnresolvedBlockAddress() {
7673
return unresolvedBlockAddressOp;
7774
}
7875

7976
private:
8077
// Maps a (function name, label name) pair to the corresponding BlockTagOp.
8178
// Used to resolve CIR LabelOps into their LLVM BlockTagOp.
82-
llvm::DenseMap<std::pair<llvm::StringRef, llvm::StringRef>,
83-
mlir::LLVM::BlockTagOp>
79+
llvm::DenseMap<cir::BlockAddrInfoAttr, mlir::LLVM::BlockTagOp>
8480
blockInfoToTagOp;
8581
// Tracks BlockAddressOps that could not yet be fully resolved because
8682
// their BlockTagOp was not available at the time of lowering. The map
8783
// stores the unresolved BlockAddressOp along with its (function name, label
8884
// name) pair so it can be patched later.
89-
llvm::DenseMap<mlir::LLVM::BlockAddressOp,
90-
std::pair<llvm::StringRef, llvm::StringRef>>
85+
llvm::DenseMap<mlir::LLVM::BlockAddressOp, cir::BlockAddrInfoAttr>
9186
unresolvedBlockAddressOp;
9287
int32_t blockTagOpIndex;
9388
};

clang/test/CIR/CodeGen/label-values.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void A(void) {
1212
}
1313
// CIR: cir.func dso_local @A
1414
// CIR: [[PTR:%.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] {alignment = 8 : i64}
15-
// CIR: [[BLOCK:%.*]] = cir.blockaddress(@A, "A") -> !cir.ptr<!void>
15+
// CIR: [[BLOCK:%.*]] = cir.blockaddress <@A, "A"> -> !cir.ptr<!void>
1616
// CIR: cir.store align(8) [[BLOCK]], [[PTR]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
1717
// CIR: cir.br ^bb1
1818
// CIR: ^bb1: // pred: ^bb0
@@ -43,7 +43,7 @@ void B(void) {
4343
// CIR: cir.func dso_local @B()
4444
// CIR: cir.label "B"
4545
// CIR: [[PTR:%.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] {alignment = 8 : i64}
46-
// CIR: [[BLOCK:%.*]] = cir.blockaddress(@B, "B") -> !cir.ptr<!void>
46+
// CIR: [[BLOCK:%.*]] = cir.blockaddress <@B, "B"> -> !cir.ptr<!void>
4747
// CIR: cir.store align(8) [[BLOCK]], [[PTR]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
4848
// CIR: cir.return
4949

@@ -72,8 +72,8 @@ void C(int x) {
7272
}
7373

7474
// CIR: cir.func dso_local @C
75-
// CIR: [[BLOCK1:%.*]] = cir.blockaddress(@C, "A") -> !cir.ptr<!void>
76-
// CIR: [[BLOCK2:%.*]] = cir.blockaddress(@C, "B") -> !cir.ptr<!void>
75+
// CIR: [[BLOCK1:%.*]] = cir.blockaddress <@C, "A"> -> !cir.ptr<!void>
76+
// CIR: [[BLOCK2:%.*]] = cir.blockaddress <@C, "B"> -> !cir.ptr<!void>
7777
// CIR: [[COND:%.*]] = cir.select if [[CMP:%.*]] then [[BLOCK1]] else [[BLOCK2]] : (!cir.bool, !cir.ptr<!void>, !cir.ptr<!void>) -> !cir.ptr<!void>
7878
// CIR: cir.store align(8) [[COND]], [[PTR:%.*]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
7979
// CIR: cir.br ^bb2
@@ -122,14 +122,14 @@ void D(void) {
122122
// CIR: %[[PTR:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init]
123123
// CIR: %[[PTR2:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr2", init]
124124
// CIR: %[[PTR3:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr3", init]
125-
// CIR: %[[BLK1:.*]] = cir.blockaddress(@D, "A") -> !cir.ptr<!void>
125+
// CIR: %[[BLK1:.*]] = cir.blockaddress <@D, "A"> -> !cir.ptr<!void>
126126
// CIR: cir.store align(8) %[[BLK1]], %[[PTR]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
127-
// CIR: %[[BLK2:.*]] = cir.blockaddress(@D, "A") -> !cir.ptr<!void>
127+
// CIR: %[[BLK2:.*]] = cir.blockaddress <@D, "A"> -> !cir.ptr<!void>
128128
// CIR: cir.store align(8) %[[BLK2]], %[[PTR2]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
129129
// CIR: cir.br ^bb1
130130
// CIR: ^bb1: // pred: ^bb0
131131
// CIR: cir.label "A"
132-
// CIR: %[[BLK3:.*]] = cir.blockaddress(@D, "A") -> !cir.ptr<!void>
132+
// CIR: %[[BLK3:.*]] = cir.blockaddress <@D, "A"> -> !cir.ptr<!void>
133133
// CIR: cir.store align(8) %[[BLK3]], %[[PTR3]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
134134
// CIR: cir.return
135135

clang/test/CIR/IR/block-adress.cir

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44

55
module {
66
cir.func @block_address(){
7-
%0 = cir.blockaddress(@block_address, "label") -> !cir.ptr<!void>
7+
%0 = cir.blockaddress <@block_address, "label"> -> !cir.ptr<!void>
88
cir.br ^bb1
99
^bb1:
1010
cir.label "label"
1111
cir.return
1212
}
1313
// CHECK: cir.func @block_address
14-
// CHECK: %0 = cir.blockaddress(@block_address, "label") -> !cir.ptr<!void>
14+
// CHECK: %0 = cir.blockaddress <@block_address, "label"> -> !cir.ptr<!void>
1515
// CHECK: cir.br ^bb1
1616
// CHECK: ^bb1:
1717
// CHECK: cir.label "label"
1818
// CHECK: cir.return
1919

2020
cir.func @block_address_inside_scope() -> () {
2121
cir.scope{
22-
%0 = cir.blockaddress(@block_address_inside_scope, "label") -> !cir.ptr<!void>
22+
%0 = cir.blockaddress <@block_address_inside_scope, "label"> -> !cir.ptr<!void>
2323
}
2424
cir.br ^bb1
2525
^bb1:
@@ -28,7 +28,7 @@ cir.func @block_address_inside_scope() -> () {
2828
}
2929
// CHECK: cir.func @block_address_inside_scope
3030
// CHECK: cir.scope
31-
// CHECK: %0 = cir.blockaddress(@block_address_inside_scope, "label") -> !cir.ptr<!void>
31+
// CHECK: %0 = cir.blockaddress <@block_address_inside_scope, "label"> -> !cir.ptr<!void>
3232
// CHECK: cir.label "label"
3333
// CHECK: cir.return
3434
}

clang/test/CIR/IR/invalid-block-address.cir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// expected-error@+1 {{expects an existing label target in the referenced function}}
66
cir.func @bad_block_address() -> () {
7-
%0 = cir.blockaddress(@bad_block_address, "label") -> !cir.ptr<!void>
7+
%0 = cir.blockaddress <@bad_block_address, "label"> -> !cir.ptr<!void>
88
cir.br ^bb1
99
^bb1:
1010
cir.label "wrong_label"
@@ -13,7 +13,7 @@ cir.func @bad_block_address() -> () {
1313

1414
// expected-error@+1 {{blockaddress references a different function}}
1515
cir.func @bad_block_func() -> () {
16-
%0 = cir.blockaddress(@mismatch_func, "label") -> !cir.ptr<!void>
16+
%0 = cir.blockaddress <@mismatch_func, "label"> -> !cir.ptr<!void>
1717
cir.br ^bb1
1818
^bb1:
1919
cir.label "label"

0 commit comments

Comments
 (0)