Skip to content

Commit

Permalink
Update on "[CIR][Interfaces] Implement LoopOpInterface"
Browse files Browse the repository at this point in the history
Adds an interface to generically handle lowering and analysis of loop
operations in CIR. It can also perform verification of invariants common
to all loop operations.

[ghstack-poisoned]
  • Loading branch information
sitio-couto committed Jan 22, 2024
2 parents 8293c18 + 31f8240 commit edc77c6
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 @@ -719,6 +719,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 edc77c6

Please sign in to comment.