Skip to content

Commit 7aa4f74

Browse files
tommymcmTommy McMichen
andauthored
[CIR][NFC] Add getBreakTarget method to cir::BreakOp (#1878)
`cir::BreakOp::getBreakTarget` gets the innermost `cir::LoopOpInterface` or `cir::SwitchOp` containing this `break`. For example: ``` A: for (...) { B: for(...) { break; // target = B C: switch (...) { default: break; // target = C } break; // target = A } ``` NOTE: This is a part of a broader effort I am working on to make querying CIR control flow facts more easily. If folks have any design notes or ideas, please share them. --------- Co-authored-by: Tommy McMichen <[email protected]>
1 parent d3892b7 commit 7aa4f74

File tree

5 files changed

+48
-7
lines changed

5 files changed

+48
-7
lines changed

clang/include/clang/CIR/Dialect/IR/CIRDialect.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "clang/CIR/Dialect/IR/CIROpsDialect.h.inc"
3131
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
3232
#include "clang/CIR/Dialect/IR/CIROpsStructs.h.inc"
33+
#include "clang/CIR/Dialect/IR/CIRTraits.h"
3334
#include "clang/CIR/Dialect/IR/CIRTypes.h"
3435

3536
#include "clang/CIR/Interfaces/ASTAttrInterfaces.h"

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,8 @@ def CIR_YieldOp : CIR_Op<"yield", [
10441044
// BreakOp
10451045
//===----------------------------------------------------------------------===//
10461046

1047+
def CIR_Breakable : NativeOpTrait<"cir::Breakable">;
1048+
10471049
def CIR_BreakOp : CIR_Op<"break", [Terminator]> {
10481050
let summary = "C/C++ `break` statement equivalent";
10491051
let description = [{
@@ -1053,6 +1055,10 @@ def CIR_BreakOp : CIR_Op<"break", [Terminator]> {
10531055
}];
10541056
let assemblyFormat = "attr-dict";
10551057
let hasVerifier = 1;
1058+
let extraClassDeclaration = [{
1059+
/// Find the parent operation corresponding to this break.
1060+
mlir::Operation *getBreakTarget();
1061+
}];
10561062
}
10571063

10581064
//===----------------------------------------------------------------------===//
@@ -1993,7 +1999,8 @@ def CIR_CaseOp : CIR_Op<"case", [
19931999
def CIR_SwitchOp : CIR_Op<"switch", [
19942000
SameVariadicOperandSize,
19952001
DeclareOpInterfaceMethods<RegionBranchOpInterface>,
1996-
RecursivelySpeculatable, AutomaticAllocationScope, NoRegionArguments
2002+
RecursivelySpeculatable, AutomaticAllocationScope, NoRegionArguments,
2003+
CIR_Breakable
19972004
]> {
19982005
let summary = "Switch operation";
19992006
let description = [{
@@ -2251,7 +2258,7 @@ def CIR_BrCondOp : CIR_Op<"brcond", [
22512258
//===----------------------------------------------------------------------===//
22522259

22532260
class CIR_WhileOpBase<string mnemonic> : CIR_Op<mnemonic, [
2254-
CIR_LoopOpInterface, NoRegionArguments
2261+
CIR_LoopOpInterface, CIR_Breakable, NoRegionArguments
22552262
]> {
22562263
defvar isWhile = !eq(mnemonic, "while");
22572264
let summary = "C/C++ " # !if(isWhile, "while", "do-while") # " loop";
@@ -2327,7 +2334,7 @@ def CIR_DoWhileOp : CIR_WhileOpBase<"do"> {
23272334
// ForOp
23282335
//===----------------------------------------------------------------------===//
23292336

2330-
def CIR_ForOp : CIR_Op<"for", [CIR_LoopOpInterface, NoRegionArguments]> {
2337+
def CIR_ForOp : CIR_Op<"for", [CIR_LoopOpInterface, CIR_Breakable, NoRegionArguments]> {
23312338
let summary = "C/C++ for loop counterpart";
23322339
let description = [{
23332340
Represents a C/C++ for loop. It consists of three regions:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===- CIRTraits.h - MLIR CIR Traits ----------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file declares the traits in the CIR dialect.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRTRAITS_H
14+
#define LLVM_CLANG_CIR_DIALECT_IR_CIRTRAITS_H
15+
16+
#include "mlir/Dialect/Traits.h"
17+
18+
namespace mlir {
19+
namespace OpTrait {
20+
namespace cir {
21+
22+
/// This class provides the API for ops that are known to be terminators.
23+
template <typename ConcreteType>
24+
class Breakable : public TraitBase<ConcreteType, Breakable> {};
25+
26+
} // namespace cir
27+
} // namespace OpTrait
28+
} // namespace mlir
29+
30+
#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRTRAITS_H

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,13 @@ void cir::AllocaOp::build(::mlir::OpBuilder &odsBuilder,
324324
// BreakOp
325325
//===----------------------------------------------------------------------===//
326326

327+
mlir::Operation *cir::BreakOp::getBreakTarget() {
328+
return getOperation()->getParentWithTrait<mlir::OpTrait::cir::Breakable>();
329+
}
330+
327331
LogicalResult cir::BreakOp::verify() {
328-
if (!getOperation()->getParentOfType<LoopOpInterface>() &&
329-
!getOperation()->getParentOfType<SwitchOp>())
330-
return emitOpError("must be within a loop or switch");
332+
if (!getOperation()->getParentWithTrait<mlir::OpTrait::cir::Breakable>())
333+
return emitOpError("must be within a breakable operation");
331334
return success();
332335
}
333336

clang/test/CIR/IR/invalid.cir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ cir.func @yield0() {
5353
cir.func @yieldbreak() {
5454
%0 = cir.const #true
5555
cir.if %0 {
56-
cir.break // expected-error {{op must be within a loop or switch}}
56+
cir.break // expected-error {{op must be within a breakable operation}}
5757
}
5858
cir.return
5959
}

0 commit comments

Comments
 (0)