Skip to content

Commit 2bf5e7f

Browse files
committed
Update on "[CIR][IR] Refactor do-while loops"
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]
2 parents 9132f21 + 80345fc commit 2bf5e7f

25 files changed

+493
-36
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,31 @@ def ContinueOp : CIR_Op<"continue", [Terminator]> {
721721
let hasVerifier = 1;
722722
}
723723

724+
//===----------------------------------------------------------------------===//
725+
// Resume
726+
//===----------------------------------------------------------------------===//
727+
728+
def ResumeOp : CIR_Op<"resume", [ReturnLike, Terminator,
729+
ParentOneOf<["CatchOp"]>]> {
730+
let summary = "Resumes execution after not catching exceptions";
731+
let description = [{
732+
The `cir.resume` operation terminates a region on `cir.catch`, "resuming"
733+
or continuing the unwind process. The incoming argument is of !cir.eh_info
734+
populated by `cir.try_call` and available in `cir.catch`.
735+
736+
Examples:
737+
```mlir
738+
cir.catch %4 {
739+
...
740+
fallback { cir.resume(%0) };
741+
}
742+
```
743+
}];
744+
745+
let arguments = (ins ExceptionInfoPtr:$ptr);
746+
let assemblyFormat = "$ptr attr-dict";
747+
}
748+
724749
//===----------------------------------------------------------------------===//
725750
// ScopeOp
726751
//===----------------------------------------------------------------------===//

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ def ExceptionInfoPtr : Type<
283283
]>, "void*">,
284284
BuildableType<
285285
"mlir::cir::PointerType::get($_builder.getContext(),"
286-
"mlir::cir::ExceptionInfo::get($_builder.getContext()))"> {
286+
"mlir::cir::ExceptionInfoType::get($_builder.getContext()))"> {
287287
}
288288

289289
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenDecl.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "CIRGenBuilder.h"
1515
#include "CIRGenCstEmitter.h"
1616
#include "CIRGenFunction.h"
17+
#include "CIRGenOpenMPRuntime.h"
1718
#include "EHScopeStack.h"
1819
#include "UnimplementedFeatureGuarding.h"
1920
#include "mlir/IR/Attributes.h"
@@ -37,13 +38,8 @@ CIRGenFunction::buildAutoVarAlloca(const VarDecl &D) {
3738
// TODO: (|| Ty.getAddressSpace() == LangAS::opencl_private &&
3839
// getLangOpts().OpenCL))
3940
assert(!UnimplementedFeature::openCL());
40-
assert(!UnimplementedFeature::openMP());
4141
assert(Ty.getAddressSpace() == LangAS::Default);
4242
assert(!Ty->isVariablyModifiedType() && "not implemented");
43-
assert(!getContext()
44-
.getLangOpts()
45-
.OpenMP && // !CGF.getLangOpts().OpenMPIRBuilder
46-
"not implemented");
4743
assert(!D.hasAttr<AnnotateAttr>() && "not implemented");
4844

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

6056
Address address = Address::invalid();
6157
Address allocaAddr = Address::invalid();
62-
Address openMPLocalAddr = Address::invalid();
58+
Address openMPLocalAddr =
59+
getCIRGenModule().getOpenMPRuntime().getAddressOfLocalVariable(*this, &D);
60+
assert(!getLangOpts().OpenMPIsTargetDevice && "NYI");
6361
if (getLangOpts().OpenMP && openMPLocalAddr.isValid()) {
6462
llvm_unreachable("NYI");
6563
} else if (Ty->isConstantSizeType()) {

clang/lib/CIR/CodeGen/CIRGenException.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,36 @@ void CIRGenFunction::buildAnyExprToExn(const Expr *e, Address addr) {
251251
DeactivateCleanupBlock(cleanup, op);
252252
}
253253

254+
mlir::Block *CIRGenFunction::getEHResumeBlock(bool isCleanup) {
255+
// Just like some other try/catch related logic: return the basic block
256+
// pointer but only use it to denote we're tracking things, but there
257+
// shouldn't be any changes to that block after work done in this function.
258+
auto catchOp = currExceptionInfo.catchOp;
259+
assert(catchOp.getNumRegions() && "expected at least one region");
260+
auto &fallbackRegion = catchOp.getRegion(catchOp.getNumRegions() - 1);
261+
262+
auto *resumeBlock = &fallbackRegion.getBlocks().back();
263+
if (!resumeBlock->empty())
264+
return resumeBlock;
265+
266+
auto ip = getBuilder().saveInsertionPoint();
267+
getBuilder().setInsertionPointToStart(resumeBlock);
268+
269+
const EHPersonality &Personality = EHPersonality::get(*this);
270+
271+
// This can always be a call because we necessarily didn't find
272+
// anything on the EH stack which needs our help.
273+
const char *RethrowName = Personality.CatchallRethrowFn;
274+
if (RethrowName != nullptr && !isCleanup) {
275+
llvm_unreachable("NYI");
276+
}
277+
278+
getBuilder().create<mlir::cir::ResumeOp>(catchOp.getLoc(),
279+
currExceptionInfo.exceptionAddr);
280+
getBuilder().restoreInsertionPoint(ip);
281+
return resumeBlock;
282+
}
283+
254284
mlir::LogicalResult CIRGenFunction::buildCXXTryStmt(const CXXTryStmt &S) {
255285
const llvm::Triple &T = getTarget().getTriple();
256286
// If we encounter a try statement on in an OpenMP target region offloaded to
@@ -288,7 +318,9 @@ mlir::LogicalResult CIRGenFunction::buildCXXTryStmt(const CXXTryStmt &S) {
288318
[&](mlir::OpBuilder &b, mlir::Location loc,
289319
mlir::OperationState &result) {
290320
mlir::OpBuilder::InsertionGuard guard(b);
291-
for (int i = 0, e = numHandlers; i != e; ++i) {
321+
// Once for each handler and one for fallback (which could be a
322+
// resume or rethrow).
323+
for (int i = 0, e = numHandlers + 1; i != e; ++i) {
292324
auto *r = result.addRegion();
293325
builder.createBlock(r);
294326
}
@@ -346,11 +378,25 @@ static void buildCatchDispatchBlock(CIRGenFunction &CGF,
346378
// Check for address space mismatch: if (typeValue->getType() != argTy)
347379
assert(!UnimplementedFeature::addressSpace());
348380

381+
bool nextIsEnd = false;
349382
// If this is the last handler, we're at the end, and the next
350383
// block is the block for the enclosing EH scope. Make sure to call
351384
// getEHDispatchBlock for caching it.
352-
if (i + 1 == e)
385+
if (i + 1 == e) {
353386
(void)CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());
387+
nextIsEnd = true;
388+
389+
// If the next handler is a catch-all, we're at the end, and the
390+
// next block is that handler.
391+
} else if (catchScope.getHandler(i + 1).isCatchAll()) {
392+
// Block already created when creating CatchOp, just mark this
393+
// is the end.
394+
nextIsEnd = true;
395+
}
396+
397+
// If the next handler is a catch-all, we're completely done.
398+
if (nextIsEnd)
399+
return;
354400
}
355401
}
356402

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

554600
// Otherwise, we should look at the actual scope.
555601
EHScope &scope = *EHStack.find(si);

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "CIRGenCstEmitter.h"
1616
#include "CIRGenFunction.h"
1717
#include "CIRGenModule.h"
18+
#include "CIRGenOpenMPRuntime.h"
1819
#include "CIRGenValue.h"
1920
#include "UnimplementedFeatureGuarding.h"
2021

@@ -759,8 +760,11 @@ LValue CIRGenFunction::buildDeclRefLValue(const DeclRefExpr *E) {
759760
if (auto *FD = LambdaCaptureFields.lookup(VD))
760761
return buildCapturedFieldLValue(*this, FD, CXXABIThisValue);
761762
assert(!UnimplementedFeature::CGCapturedStmtInfo() && "NYI");
762-
llvm_unreachable("NYI");
763+
// TODO[OpenMP]: Find the appropiate captured variable value and return
764+
// it.
765+
// TODO[OpenMP]: Set non-temporal information in the captured LVal.
763766
// LLVM codegen:
767+
assert(!UnimplementedFeature::openMP());
764768
// Address addr = GetAddrOfBlockDecl(VD);
765769
// return MakeAddrLValue(addr, T, AlignmentSource::Decl);
766770
}
@@ -910,9 +914,9 @@ LValue CIRGenFunction::buildBinaryOperatorLValue(const BinaryOperator *E) {
910914
} else {
911915
buildStoreThroughLValue(RV, LV);
912916
}
913-
914-
assert(!getContext().getLangOpts().OpenMP &&
915-
"last priv cond not implemented");
917+
if (getLangOpts().OpenMP)
918+
CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this,
919+
E->getLHS());
916920
return LV;
917921
}
918922

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "CIRDataLayout.h"
1515
#include "CIRGenFunction.h"
1616
#include "CIRGenModule.h"
17+
#include "CIRGenOpenMPRuntime.h"
1718
#include "UnimplementedFeatureGuarding.h"
1819

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

1808-
assert(!CGF.getLangOpts().OpenMP && "Not implemented");
1809+
if (CGF.getLangOpts().OpenMP)
1810+
CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF,
1811+
E->getLHS());
18091812
return LHSLV;
18101813
}
18111814

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "CIRGenFunction.h"
1414
#include "CIRGenCXXABI.h"
1515
#include "CIRGenModule.h"
16+
#include "CIRGenOpenMPRuntime.h"
1617
#include "UnimplementedFeatureGuarding.h"
1718

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

976977
if (getLangOpts().OpenMP && CurCodeDecl)
977-
llvm_unreachable("NYI");
978+
CGM.getOpenMPRuntime().emitFunctionProlog(*this, CurCodeDecl);
978979

979980
// TODO: buildFunctionProlog
980981

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,9 @@ class CIRGenFunction : public CIRGenTypeCache {
928928
mlir::LogicalResult buildBreakStmt(const clang::BreakStmt &S);
929929
mlir::LogicalResult buildContinueStmt(const clang::ContinueStmt &S);
930930

931+
// OpenMP gen functions:
932+
mlir::LogicalResult buildOMPParallelDirective(const OMPParallelDirective &S);
933+
931934
LValue buildOpaqueValueLValue(const OpaqueValueExpr *e);
932935

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

1506-
/// Emits landing pad information for the current EH stack.
1509+
/// Emits try/catch information for the current EH stack.
15071510
mlir::Operation *buildLandingPad();
1511+
mlir::Block *getEHResumeBlock(bool isCleanup);
15081512
mlir::Block *getEHDispatchBlock(EHScopeStack::stable_iterator scope);
15091513

15101514
mlir::Operation *getInvokeDestImpl();

0 commit comments

Comments
 (0)