Skip to content

Commit

Permalink
added has_label attr and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gitoleg committed Apr 23, 2024
1 parent 80efb6f commit 0a7ce23
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 15 deletions.
15 changes: 6 additions & 9 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2506,6 +2506,8 @@ def FuncOp : CIR_Op<"func", [
can also be specified `global_ctor(<prio>)`. Similarly, for global destructors
both `global_dtor` and `global_dtor(<prio>)` are available.

The `has_labels` indicates whether labels and goto-s operations exists in a function.

Example:

```mlir
Expand Down Expand Up @@ -2538,6 +2540,7 @@ def FuncOp : CIR_Op<"func", [
UnitAttr:$coroutine,
UnitAttr:$lambda,
UnitAttr:$no_proto,
UnitAttr:$has_labels,
DefaultValuedAttr<GlobalLinkageKind,
"GlobalLinkageKind::ExternalLinkage">:$linkage,
ExtraFuncAttr:$extra_attrs,
Expand Down Expand Up @@ -3644,22 +3647,16 @@ def SwitchFlatOp : CIR_Op<"switch.flat", [AttrSizedOperandSegments, Terminator]>
}

def GotoOp : CIR_Op<"goto", [Terminator]> {
let summary = "goto";
let description = [{ }];

let description = [{ Transfers control to the specified label }];
let arguments = (ins StrAttr:$label);
let assemblyFormat = [{ $label attr-dict }];


}

def LabelOp : CIR_Op<"label"> {
let summary = "label";
let description = [{ }];

let description = [{ An identifier which may be referred by Goto operation }];
let arguments = (ins StrAttr:$label);
let assemblyFormat = [{ $label attr-dict }];

let hasVerifier = 1;
}

//===----------------------------------------------------------------------===//
Expand Down
7 changes: 5 additions & 2 deletions clang/include/clang/CIR/Dialect/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,11 @@ def FlattenCFG : Pass<"cir-flatten-cfg"> {
}

def GotoSolver : Pass<"cir-goto-solver"> {
let summary = "TODO";
let description = [{ TODO }];
let summary = "Replaces goto operatations with branches";
let description = [{
This pass transforms CIR and replaces goto-s with branch
operations to the proper blocks.
}];
let constructor = "mlir::createGotoSolverPass()";
let dependentDialects = ["cir::CIRDialect"];
}
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ mlir::LogicalResult CIRGenFunction::buildLabelStmt(const clang::LabelStmt &S) {
if (buildLabel(S.getDecl()).failed())
return mlir::failure();

auto fn = dyn_cast<mlir::cir::FuncOp>(CurFn);
fn.setHasLabels(true);

// IsEHa: not implemented.
assert(!(getContext().getLangOpts().EHAsynch && S.isSideEntry()));

Expand Down
21 changes: 20 additions & 1 deletion clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1984,6 +1984,10 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
}
state.addAttribute(getExtraAttrsAttrName(state.name), extraAttrs);

auto hasLabelsNameAttr = getGlobalDtorAttrName(state.name);
if (::mlir::succeeded(parser.parseOptionalKeyword(hasLabelsNameAttr.strref())))
state.addAttribute(hasLabelsNameAttr, parser.getBuilder().getUnitAttr());

// Parse the optional function body.
auto *body = state.addRegion();
OptionalParseResult parseResult = parser.parseOptionalRegion(
Expand Down Expand Up @@ -2065,7 +2069,7 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
{getSymVisibilityAttrName(), getAliaseeAttrName(),
getFunctionTypeAttrName(), getLinkageAttrName(), getBuiltinAttrName(),
getNoProtoAttrName(), getGlobalCtorAttrName(), getGlobalDtorAttrName(),
getExtraAttrsAttrName()});
getExtraAttrsAttrName(), getHasLabelsAttrName()});

if (auto aliaseeName = getAliasee()) {
p << " alias(";
Expand All @@ -2091,6 +2095,9 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
p << ")";
}

if (getHasLabels())
p << " has_labels";

// Print the body if this is not an external function.
Region &body = getOperation()->getRegion(0);
if (!body.empty()) {
Expand Down Expand Up @@ -3067,6 +3074,18 @@ LogicalResult BinOp::verify() {
return mlir::success();
}

//===----------------------------------------------------------------------===//
// LabelOp Definitions
//===----------------------------------------------------------------------===//

LogicalResult LabelOp::verify() {
auto* op = getOperation();
auto* blk = op->getBlock();
if (&blk->front() != op)
return emitError() << "LabelOp must be the first operation in a block";
return mlir::success();
}

//===----------------------------------------------------------------------===//
// TableGen'd op method definitions
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/Dialect/Transforms/GotoSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/Passes.h"
#include <iostream>

using namespace mlir;
using namespace mlir::cir;
Expand Down Expand Up @@ -47,7 +46,8 @@ static void process(mlir::cir::FuncOp func) {
void GotoSolverPass::runOnOperation() {
SmallVector<Operation *, 16> ops;
getOperation()->walk([&](mlir::cir::FuncOp op) {
process(op);
if (op.getHasLabels())
process(op);
});
}

Expand Down
31 changes: 30 additions & 1 deletion clang/test/CIR/CodeGen/goto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,35 @@ int shouldCreateBlkForGoto(int a) {
// NOFLAT: cir.goto "exit"
// NOFLAT: }

void severalLabelsInARow(int a) {
int b = a;
goto end1;
b = b + 1;
goto end2;
end1:
end2:
b = b + 2;
}
// NOFLAT: cir.func @_Z19severalLabelsInARowi
// NOFLAT: ^bb[[#BLK1:]]:
// NOFLAT: cir.label "end1"
// NOFLAT: cir.br ^bb[[#BLK2:]]
// NOFLAT: ^bb[[#BLK2]]:
// NOFLAT: cir.label "end2"

void severalGotosInARow(int a) {
int b = a;
goto end;
goto end;
end:
b = b + 2;
}
// NOFLAT: cir.func @_Z18severalGotosInARowi
// NOFLAT: cir.goto "end"
// NOFLAT: ^bb[[#BLK1:]]:
// NOFLAT: cir.goto "end"
// NOFLAT: ^bb[[#BLK2:]]:
// NOFLAT: cir.label "end"

int jumpIntoLoop(int* ar) {

Expand Down Expand Up @@ -164,7 +193,7 @@ int jumpFromLoop(int* ar) {

if (!ar) {
err:
return -1;
return -1;
}

while (ar) {
Expand Down

0 comments on commit 0a7ce23

Please sign in to comment.