Skip to content

Commit

Permalink
Update on "[CIR][IR] Refactor do-while loops"
Browse files Browse the repository at this point in the history
Creates a separate C/C++ operation for do-while loops, while keeping the
LoopOpInterface to generically handle loops. This simplifies the IR
generation and printing/parsing of do-while loops. It also allows us to
define it regions in the order that they are executed, which is useful
for the lifetime analysis.

[ghstack-poisoned]
  • Loading branch information
sitio-couto committed Jan 22, 2024
2 parents 9132f21 + 80345fc commit 2bf5e7f
Show file tree
Hide file tree
Showing 25 changed files with 493 additions and 36 deletions.
25 changes: 25 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,31 @@ def ContinueOp : CIR_Op<"continue", [Terminator]> {
let hasVerifier = 1;
}

//===----------------------------------------------------------------------===//
// Resume
//===----------------------------------------------------------------------===//

def ResumeOp : CIR_Op<"resume", [ReturnLike, Terminator,
ParentOneOf<["CatchOp"]>]> {
let summary = "Resumes execution after not catching exceptions";
let description = [{
The `cir.resume` operation terminates a region on `cir.catch`, "resuming"
or continuing the unwind process. The incoming argument is of !cir.eh_info
populated by `cir.try_call` and available in `cir.catch`.

Examples:
```mlir
cir.catch %4 {
...
fallback { cir.resume(%0) };
}
```
}];

let arguments = (ins ExceptionInfoPtr:$ptr);
let assemblyFormat = "$ptr attr-dict";
}

//===----------------------------------------------------------------------===//
// ScopeOp
//===----------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ def ExceptionInfoPtr : Type<
]>, "void*">,
BuildableType<
"mlir::cir::PointerType::get($_builder.getContext(),"
"mlir::cir::ExceptionInfo::get($_builder.getContext()))"> {
"mlir::cir::ExceptionInfoType::get($_builder.getContext()))"> {
}

//===----------------------------------------------------------------------===//
Expand Down
10 changes: 4 additions & 6 deletions clang/lib/CIR/CodeGen/CIRGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "CIRGenBuilder.h"
#include "CIRGenCstEmitter.h"
#include "CIRGenFunction.h"
#include "CIRGenOpenMPRuntime.h"
#include "EHScopeStack.h"
#include "UnimplementedFeatureGuarding.h"
#include "mlir/IR/Attributes.h"
Expand All @@ -37,13 +38,8 @@ CIRGenFunction::buildAutoVarAlloca(const VarDecl &D) {
// TODO: (|| Ty.getAddressSpace() == LangAS::opencl_private &&
// getLangOpts().OpenCL))
assert(!UnimplementedFeature::openCL());
assert(!UnimplementedFeature::openMP());
assert(Ty.getAddressSpace() == LangAS::Default);
assert(!Ty->isVariablyModifiedType() && "not implemented");
assert(!getContext()
.getLangOpts()
.OpenMP && // !CGF.getLangOpts().OpenMPIRBuilder
"not implemented");
assert(!D.hasAttr<AnnotateAttr>() && "not implemented");

auto loc = getLoc(D.getSourceRange());
Expand All @@ -59,7 +55,9 @@ CIRGenFunction::buildAutoVarAlloca(const VarDecl &D) {

Address address = Address::invalid();
Address allocaAddr = Address::invalid();
Address openMPLocalAddr = Address::invalid();
Address openMPLocalAddr =
getCIRGenModule().getOpenMPRuntime().getAddressOfLocalVariable(*this, &D);
assert(!getLangOpts().OpenMPIsTargetDevice && "NYI");
if (getLangOpts().OpenMP && openMPLocalAddr.isValid()) {
llvm_unreachable("NYI");
} else if (Ty->isConstantSizeType()) {
Expand Down
52 changes: 49 additions & 3 deletions clang/lib/CIR/CodeGen/CIRGenException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,36 @@ void CIRGenFunction::buildAnyExprToExn(const Expr *e, Address addr) {
DeactivateCleanupBlock(cleanup, op);
}

mlir::Block *CIRGenFunction::getEHResumeBlock(bool isCleanup) {
// Just like some other try/catch related logic: return the basic block
// pointer but only use it to denote we're tracking things, but there
// shouldn't be any changes to that block after work done in this function.
auto catchOp = currExceptionInfo.catchOp;
assert(catchOp.getNumRegions() && "expected at least one region");
auto &fallbackRegion = catchOp.getRegion(catchOp.getNumRegions() - 1);

auto *resumeBlock = &fallbackRegion.getBlocks().back();
if (!resumeBlock->empty())
return resumeBlock;

auto ip = getBuilder().saveInsertionPoint();
getBuilder().setInsertionPointToStart(resumeBlock);

const EHPersonality &Personality = EHPersonality::get(*this);

// This can always be a call because we necessarily didn't find
// anything on the EH stack which needs our help.
const char *RethrowName = Personality.CatchallRethrowFn;
if (RethrowName != nullptr && !isCleanup) {
llvm_unreachable("NYI");
}

getBuilder().create<mlir::cir::ResumeOp>(catchOp.getLoc(),
currExceptionInfo.exceptionAddr);
getBuilder().restoreInsertionPoint(ip);
return resumeBlock;
}

mlir::LogicalResult CIRGenFunction::buildCXXTryStmt(const CXXTryStmt &S) {
const llvm::Triple &T = getTarget().getTriple();
// If we encounter a try statement on in an OpenMP target region offloaded to
Expand Down Expand Up @@ -288,7 +318,9 @@ mlir::LogicalResult CIRGenFunction::buildCXXTryStmt(const CXXTryStmt &S) {
[&](mlir::OpBuilder &b, mlir::Location loc,
mlir::OperationState &result) {
mlir::OpBuilder::InsertionGuard guard(b);
for (int i = 0, e = numHandlers; i != e; ++i) {
// Once for each handler and one for fallback (which could be a
// resume or rethrow).
for (int i = 0, e = numHandlers + 1; i != e; ++i) {
auto *r = result.addRegion();
builder.createBlock(r);
}
Expand Down Expand Up @@ -346,11 +378,25 @@ static void buildCatchDispatchBlock(CIRGenFunction &CGF,
// Check for address space mismatch: if (typeValue->getType() != argTy)
assert(!UnimplementedFeature::addressSpace());

bool nextIsEnd = false;
// If this is the last handler, we're at the end, and the next
// block is the block for the enclosing EH scope. Make sure to call
// getEHDispatchBlock for caching it.
if (i + 1 == e)
if (i + 1 == e) {
(void)CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());
nextIsEnd = true;

// If the next handler is a catch-all, we're at the end, and the
// next block is that handler.
} else if (catchScope.getHandler(i + 1).isCatchAll()) {
// Block already created when creating CatchOp, just mark this
// is the end.
nextIsEnd = true;
}

// If the next handler is a catch-all, we're completely done.
if (nextIsEnd)
return;
}
}

Expand Down Expand Up @@ -549,7 +595,7 @@ CIRGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {
// The dispatch block for the end of the scope chain is a block that
// just resumes unwinding.
if (si == EHStack.stable_end())
llvm_unreachable("NYI");
return getEHResumeBlock(true);

// Otherwise, we should look at the actual scope.
EHScope &scope = *EHStack.find(si);
Expand Down
12 changes: 8 additions & 4 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "CIRGenCstEmitter.h"
#include "CIRGenFunction.h"
#include "CIRGenModule.h"
#include "CIRGenOpenMPRuntime.h"
#include "CIRGenValue.h"
#include "UnimplementedFeatureGuarding.h"

Expand Down Expand Up @@ -759,8 +760,11 @@ LValue CIRGenFunction::buildDeclRefLValue(const DeclRefExpr *E) {
if (auto *FD = LambdaCaptureFields.lookup(VD))
return buildCapturedFieldLValue(*this, FD, CXXABIThisValue);
assert(!UnimplementedFeature::CGCapturedStmtInfo() && "NYI");
llvm_unreachable("NYI");
// TODO[OpenMP]: Find the appropiate captured variable value and return
// it.
// TODO[OpenMP]: Set non-temporal information in the captured LVal.
// LLVM codegen:
assert(!UnimplementedFeature::openMP());
// Address addr = GetAddrOfBlockDecl(VD);
// return MakeAddrLValue(addr, T, AlignmentSource::Decl);
}
Expand Down Expand Up @@ -910,9 +914,9 @@ LValue CIRGenFunction::buildBinaryOperatorLValue(const BinaryOperator *E) {
} else {
buildStoreThroughLValue(RV, LV);
}

assert(!getContext().getLangOpts().OpenMP &&
"last priv cond not implemented");
if (getLangOpts().OpenMP)
CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this,
E->getLHS());
return LV;
}

Expand Down
5 changes: 4 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "CIRDataLayout.h"
#include "CIRGenFunction.h"
#include "CIRGenModule.h"
#include "CIRGenOpenMPRuntime.h"
#include "UnimplementedFeatureGuarding.h"

#include "clang/AST/StmtVisitor.h"
Expand Down Expand Up @@ -1805,7 +1806,9 @@ LValue ScalarExprEmitter::buildCompoundAssignLValue(
else
CGF.buildStoreThroughLValue(RValue::get(Result), LHSLV);

assert(!CGF.getLangOpts().OpenMP && "Not implemented");
if (CGF.getLangOpts().OpenMP)
CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF,
E->getLHS());
return LHSLV;
}

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "CIRGenFunction.h"
#include "CIRGenCXXABI.h"
#include "CIRGenModule.h"
#include "CIRGenOpenMPRuntime.h"
#include "UnimplementedFeatureGuarding.h"

#include "clang/AST/ASTLambda.h"
Expand Down Expand Up @@ -974,7 +975,7 @@ void CIRGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
// TODO: prologuecleanupdepth

if (getLangOpts().OpenMP && CurCodeDecl)
llvm_unreachable("NYI");
CGM.getOpenMPRuntime().emitFunctionProlog(*this, CurCodeDecl);

// TODO: buildFunctionProlog

Expand Down
6 changes: 5 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,9 @@ class CIRGenFunction : public CIRGenTypeCache {
mlir::LogicalResult buildBreakStmt(const clang::BreakStmt &S);
mlir::LogicalResult buildContinueStmt(const clang::ContinueStmt &S);

// OpenMP gen functions:
mlir::LogicalResult buildOMPParallelDirective(const OMPParallelDirective &S);

LValue buildOpaqueValueLValue(const OpaqueValueExpr *e);

/// Emit code to compute a designator that specifies the location
Expand Down Expand Up @@ -1503,8 +1506,9 @@ class CIRGenFunction : public CIRGenTypeCache {
bool isConditional() const { return IsConditional; }
};

/// Emits landing pad information for the current EH stack.
/// Emits try/catch information for the current EH stack.
mlir::Operation *buildLandingPad();
mlir::Block *getEHResumeBlock(bool isCleanup);
mlir::Block *getEHDispatchBlock(EHScopeStack::stable_iterator scope);

mlir::Operation *getInvokeDestImpl();
Expand Down
Loading

0 comments on commit 2bf5e7f

Please sign in to comment.