Skip to content
Merged
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
25 changes: 25 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,31 @@ def CIR_AddressPointAttr : CIR_Attr<"AddressPoint", "address_point"> {
}];
}

//===----------------------------------------------------------------------===//
// CIR_BlockAddrInfoAttr
//===----------------------------------------------------------------------===//

def CIR_BlockAddrInfoAttr : CIR_Attr<"BlockAddrInfo", "block_addr_info"> {
let summary = "Block Addres attribute";
let description = [{
This attribute is used to represent the address of a basic block
within a function. It combines the symbol reference to a function
with the name of a label inside that function.
}];
let parameters = (ins "mlir::FlatSymbolRefAttr":$func,
"mlir::StringAttr":$label);

let assemblyFormat = "`<` $func `,` $label `>`";
let builders = [
AttrBuilder<(ins "llvm::StringRef":$func_name,
"llvm::StringRef":$label_name
), [{
return $_get($_ctxt, mlir::FlatSymbolRefAttr::get($_ctxt, func_name),
mlir::StringAttr::get($_ctxt, label_name));
}]>
];
}

include "clang/CIR/Dialect/IR/CIRTBAAAttrs.td"

include "clang/CIR/Dialect/IR/CIROpenCLAttrs.td"
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -6144,10 +6144,10 @@ def CIR_BlockAddressOp : CIR_Op<"blockaddress", [Pure]> {
```
}];

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

Expand Down
12 changes: 4 additions & 8 deletions clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,11 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {

mlir::Value VisitAddrLabelExpr(const AddrLabelExpr *e) {
auto func = cast<cir::FuncOp>(CGF.CurFn);
llvm::StringRef symName = func.getSymName();
mlir::FlatSymbolRefAttr funName =
mlir::FlatSymbolRefAttr::get(&CGF.getMLIRContext(), symName);
mlir::StringAttr labelName =
mlir::StringAttr::get(&CGF.getMLIRContext(), e->getLabel()->getName());
auto blockInfoAttr = cir::BlockAddrInfoAttr::get(
&CGF.getMLIRContext(), func.getSymName(), e->getLabel()->getName());
return cir::BlockAddressOp::create(Builder, CGF.getLoc(e->getSourceRange()),
CGF.convertType(e->getType()), funName,
labelName);
;
CGF.convertType(e->getType()),
blockInfoAttr);
}
mlir::Value VisitSizeOfPackExpr(SizeOfPackExpr *E) {
llvm_unreachable("NYI");
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2939,12 +2939,12 @@ LogicalResult cir::FuncOp::verify() {
} else if (auto goTo = dyn_cast<cir::GotoOp>(op)) {
gotos.insert(goTo.getLabel());
} else if (auto blkAdd = dyn_cast<cir::BlockAddressOp>(op)) {
if (blkAdd.getFunc() != getSymName()) {
if (blkAdd.getBlockAddrInfoAttr().getFunc().getAttr() != getSymName()) {
// Stop the walk early, no need to continue
invalidBlockAddress = true;
return mlir::WalkResult::interrupt();
}
blockAddresses.insert(blkAdd.getLabel());
blockAddresses.insert(blkAdd.getBlockAddrInfoAttr().getLabel());
}
return mlir::WalkResult::advance();
});
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/Dialect/Transforms/GotoSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void process(cir::FuncOp func) {
} else if (auto goTo = dyn_cast<cir::GotoOp>(op)) {
gotos.push_back(goTo);
} else if (auto blockAddr = dyn_cast<cir::BlockAddressOp>(op)) {
blockAddrLabel.insert(blockAddr.getLabel());
blockAddrLabel.insert(blockAddr.getBlockAddrInfo().getLabel());
}
});

Expand Down
17 changes: 9 additions & 8 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4518,7 +4518,9 @@ mlir::LogicalResult CIRToLLVMLabelOpLowering::matchAndRewrite(
auto blockTagOp =
mlir::LLVM::BlockTagOp::create(rewriter, op->getLoc(), tagAttr);
auto func = op->getParentOfType<mlir::LLVM::LLVMFuncOp>();
blockInfoAddr.mapBlockTag(func.getSymName(), op.getLabel(), blockTagOp);
auto blockInfoAttr =
cir::BlockAddrInfoAttr::get(ctx, func.getSymName(), op.getLabel());
blockInfoAddr.mapBlockTag(blockInfoAttr, blockTagOp);
rewriter.eraseOp(op);

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

mlir::LLVM::BlockTagOp matchLabel =
blockInfoAddr.lookupBlockTag(op.getFunc(), op.getLabel());
blockInfoAddr.lookupBlockTag(op.getBlockAddrInfoAttr());
mlir::LLVM::BlockTagAttr tagAttr;
if (!matchLabel)
// If the BlockTagOp has not been emitted yet, use a placeholder.
Expand All @@ -4540,13 +4542,13 @@ mlir::LogicalResult CIRToLLVMBlockAddressOpLowering::matchAndRewrite(
else
tagAttr = matchLabel.getTag();

auto blkAddr = mlir::LLVM::BlockAddressAttr::get(rewriter.getContext(),
op.getFuncAttr(), tagAttr);
auto blkAddr = mlir::LLVM::BlockAddressAttr::get(
rewriter.getContext(), op.getBlockAddrInfoAttr().getFunc(), tagAttr);
rewriter.setInsertionPoint(op);
auto newOp = mlir::LLVM::BlockAddressOp::create(
rewriter, op.getLoc(), mlir::LLVM::LLVMPointerType::get(ctx), blkAddr);
if (!matchLabel)
blockInfoAddr.addUnresolvedBlockAddress(newOp, op.getFunc(), op.getLabel());
blockInfoAddr.addUnresolvedBlockAddress(newOp, op.getBlockAddrInfoAttr());
rewriter.replaceOp(op, newOp);
return mlir::success();
}
Expand Down Expand Up @@ -5058,10 +5060,9 @@ void ConvertCIRToLLVMPass::resolveBlockAddressOp(
for (auto &[blockAddOp, blockInfo] :
blockInfoAddr.getUnresolvedBlockAddress()) {
mlir::LLVM::BlockTagOp resolvedLabel =
blockInfoAddr.lookupBlockTag(blockInfo.first, blockInfo.second);
blockInfoAddr.lookupBlockTag(blockInfo);
assert(resolvedLabel && "expected BlockTagOp to already be emitted");
auto fnSym =
mlir::FlatSymbolRefAttr::get(module.getContext(), blockInfo.first);
auto fnSym = blockInfo.getFunc();
auto blkAddTag = mlir::LLVM::BlockAddressAttr::get(
opBuilder.getContext(), fnSym, resolvedLabel.getTagAttr());
blockAddOp.setBlockAddrAttr(blkAddTag);
Expand Down
23 changes: 9 additions & 14 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,45 +49,40 @@ struct LLVMBlockAddressInfo {
// Get the next tag index
uint32_t getTagIndex() { return blockTagOpIndex++; }

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

// Lookup a BlockTagOp, may return nullptr if not yet registered.
mlir::LLVM::BlockTagOp lookupBlockTag(llvm::StringRef func,
llvm::StringRef label) const {
return blockInfoToTagOp.lookup({func, label});
mlir::LLVM::BlockTagOp lookupBlockTag(cir::BlockAddrInfoAttr info) const {
return blockInfoToTagOp.lookup(info);
}

// Record an unresolved BlockAddressOp that needs patching later.
void addUnresolvedBlockAddress(mlir::LLVM::BlockAddressOp op,
llvm::StringRef func, llvm::StringRef label) {
unresolvedBlockAddressOp.try_emplace(op, std::make_pair(func, label));
cir::BlockAddrInfoAttr info) {
unresolvedBlockAddressOp.try_emplace(op, info);
}

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

llvm::DenseMap<mlir::LLVM::BlockAddressOp,
std::pair<llvm::StringRef, llvm::StringRef>> &
llvm::DenseMap<mlir::LLVM::BlockAddressOp, cir::BlockAddrInfoAttr> &
getUnresolvedBlockAddress() {
return unresolvedBlockAddressOp;
}

private:
// Maps a (function name, label name) pair to the corresponding BlockTagOp.
// Used to resolve CIR LabelOps into their LLVM BlockTagOp.
llvm::DenseMap<std::pair<llvm::StringRef, llvm::StringRef>,
mlir::LLVM::BlockTagOp>
llvm::DenseMap<cir::BlockAddrInfoAttr, mlir::LLVM::BlockTagOp>
blockInfoToTagOp;
// Tracks BlockAddressOps that could not yet be fully resolved because
// their BlockTagOp was not available at the time of lowering. The map
// stores the unresolved BlockAddressOp along with its (function name, label
// name) pair so it can be patched later.
llvm::DenseMap<mlir::LLVM::BlockAddressOp,
std::pair<llvm::StringRef, llvm::StringRef>>
llvm::DenseMap<mlir::LLVM::BlockAddressOp, cir::BlockAddrInfoAttr>
unresolvedBlockAddressOp;
int32_t blockTagOpIndex;
};
Expand Down
14 changes: 7 additions & 7 deletions clang/test/CIR/CodeGen/label-values.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void A(void) {
}
// CIR: cir.func dso_local @A
// CIR: [[PTR:%.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] {alignment = 8 : i64}
// CIR: [[BLOCK:%.*]] = cir.blockaddress(@A, "A") -> !cir.ptr<!void>
// CIR: [[BLOCK:%.*]] = cir.blockaddress <@A, "A"> -> !cir.ptr<!void>
// CIR: cir.store align(8) [[BLOCK]], [[PTR]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CIR: cir.br ^bb1
// CIR: ^bb1: // pred: ^bb0
Expand Down Expand Up @@ -43,7 +43,7 @@ void B(void) {
// CIR: cir.func dso_local @B()
// CIR: cir.label "B"
// CIR: [[PTR:%.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] {alignment = 8 : i64}
// CIR: [[BLOCK:%.*]] = cir.blockaddress(@B, "B") -> !cir.ptr<!void>
// CIR: [[BLOCK:%.*]] = cir.blockaddress <@B, "B"> -> !cir.ptr<!void>
// CIR: cir.store align(8) [[BLOCK]], [[PTR]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CIR: cir.return

Expand Down Expand Up @@ -72,8 +72,8 @@ void C(int x) {
}

// CIR: cir.func dso_local @C
// CIR: [[BLOCK1:%.*]] = cir.blockaddress(@C, "A") -> !cir.ptr<!void>
// CIR: [[BLOCK2:%.*]] = cir.blockaddress(@C, "B") -> !cir.ptr<!void>
// CIR: [[BLOCK1:%.*]] = cir.blockaddress <@C, "A"> -> !cir.ptr<!void>
// CIR: [[BLOCK2:%.*]] = cir.blockaddress <@C, "B"> -> !cir.ptr<!void>
// CIR: [[COND:%.*]] = cir.select if [[CMP:%.*]] then [[BLOCK1]] else [[BLOCK2]] : (!cir.bool, !cir.ptr<!void>, !cir.ptr<!void>) -> !cir.ptr<!void>
// CIR: cir.store align(8) [[COND]], [[PTR:%.*]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CIR: cir.br ^bb2
Expand Down Expand Up @@ -122,14 +122,14 @@ void D(void) {
// CIR: %[[PTR:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init]
// CIR: %[[PTR2:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr2", init]
// CIR: %[[PTR3:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr3", init]
// CIR: %[[BLK1:.*]] = cir.blockaddress(@D, "A") -> !cir.ptr<!void>
// CIR: %[[BLK1:.*]] = cir.blockaddress <@D, "A"> -> !cir.ptr<!void>
// CIR: cir.store align(8) %[[BLK1]], %[[PTR]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CIR: %[[BLK2:.*]] = cir.blockaddress(@D, "A") -> !cir.ptr<!void>
// CIR: %[[BLK2:.*]] = cir.blockaddress <@D, "A"> -> !cir.ptr<!void>
// CIR: cir.store align(8) %[[BLK2]], %[[PTR2]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CIR: cir.br ^bb1
// CIR: ^bb1: // pred: ^bb0
// CIR: cir.label "A"
// CIR: %[[BLK3:.*]] = cir.blockaddress(@D, "A") -> !cir.ptr<!void>
// CIR: %[[BLK3:.*]] = cir.blockaddress <@D, "A"> -> !cir.ptr<!void>
// CIR: cir.store align(8) %[[BLK3]], %[[PTR3]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CIR: cir.return

Expand Down
8 changes: 4 additions & 4 deletions clang/test/CIR/IR/block-adress.cir
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@

module {
cir.func @block_address(){
%0 = cir.blockaddress(@block_address, "label") -> !cir.ptr<!void>
%0 = cir.blockaddress <@block_address, "label"> -> !cir.ptr<!void>
cir.br ^bb1
^bb1:
cir.label "label"
cir.return
}
// CHECK: cir.func @block_address
// CHECK: %0 = cir.blockaddress(@block_address, "label") -> !cir.ptr<!void>
// CHECK: %0 = cir.blockaddress <@block_address, "label"> -> !cir.ptr<!void>
// CHECK: cir.br ^bb1
// CHECK: ^bb1:
// CHECK: cir.label "label"
// CHECK: cir.return

cir.func @block_address_inside_scope() -> () {
cir.scope{
%0 = cir.blockaddress(@block_address_inside_scope, "label") -> !cir.ptr<!void>
%0 = cir.blockaddress <@block_address_inside_scope, "label"> -> !cir.ptr<!void>
}
cir.br ^bb1
^bb1:
Expand All @@ -28,7 +28,7 @@ cir.func @block_address_inside_scope() -> () {
}
// CHECK: cir.func @block_address_inside_scope
// CHECK: cir.scope
// CHECK: %0 = cir.blockaddress(@block_address_inside_scope, "label") -> !cir.ptr<!void>
// CHECK: %0 = cir.blockaddress <@block_address_inside_scope, "label"> -> !cir.ptr<!void>
// CHECK: cir.label "label"
// CHECK: cir.return
}
4 changes: 2 additions & 2 deletions clang/test/CIR/IR/invalid-block-address.cir
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

// expected-error@+1 {{blockaddress references a different function}}
cir.func @bad_block_func() -> () {
%0 = cir.blockaddress(@mismatch_func, "label") -> !cir.ptr<!void>
%0 = cir.blockaddress <@mismatch_func, "label"> -> !cir.ptr<!void>
cir.br ^bb1
^bb1:
cir.label "label"
Expand Down
12 changes: 6 additions & 6 deletions clang/test/CIR/Transforms/goto_solver.cir
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

cir.func @a(){
%0 = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] {alignment = 8 : i64}
%1 = cir.blockaddress(@a, "label1") -> !cir.ptr<!void>
%1 = cir.blockaddress <@a, "label1"> -> !cir.ptr<!void>
cir.store align(8) %1, %0 : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
cir.br ^bb1
^bb1:
Expand All @@ -17,7 +17,7 @@ cir.func @a(){
}

// CHECK: cir.func @a()
// CHECK: %1 = cir.blockaddress(@a, "label1") -> !cir.ptr<!void>
// CHECK: %1 = cir.blockaddress <@a, "label1"> -> !cir.ptr<!void>
// CHECK: ^bb1:
// CHECK: cir.label "label1"
// CHECK: cir.br ^bb2
Expand All @@ -26,7 +26,7 @@ cir.func @a(){

cir.func @b(){
%0 = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] {alignment = 8 : i64}
%1 = cir.blockaddress(@b, "label1") -> !cir.ptr<!void>
%1 = cir.blockaddress <@b, "label1"> -> !cir.ptr<!void>
cir.store align(8) %1, %0 : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
cir.goto "label2"
^bb1:
Expand All @@ -39,7 +39,7 @@ cir.func @b(){
}

// CHECK: cir.func @b() {
// CHECK: %1 = cir.blockaddress(@b, "label1") -> !cir.ptr<!void>
// CHECK: %1 = cir.blockaddress <@b, "label1"> -> !cir.ptr<!void>
// CHECK: cir.store align(8) %1, {{.*}} : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CHECK: cir.br ^bb2
// CHECK: ^bb1:
Expand All @@ -51,13 +51,13 @@ cir.func @b(){
cir.func @c() {
cir.label "label1"
%0 = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["ptr", init] {alignment = 8 : i64}
%1 = cir.blockaddress(@c, "label1") -> !cir.ptr<!void>
%1 = cir.blockaddress <@c, "label1"> -> !cir.ptr<!void>
cir.store align(8) %1, %0 : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
cir.return
}

// CHECK: cir.func @c
// CHECK: cir.label "label1"
// CHECK: %1 = cir.blockaddress(@c, "label1") -> !cir.ptr<!void>
// CHECK: %1 = cir.blockaddress <@c, "label1"> -> !cir.ptr<!void>
// CHECK: cir.store align(8) %1, {{.*}} : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>

Loading