Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,25 +389,6 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return createCallOp(loc, callee, cir::VoidType(), operands, attrs);
}

cir::CallOp createTryCallOp(
mlir::Location loc, mlir::SymbolRefAttr callee = mlir::SymbolRefAttr(),
mlir::Type returnType = cir::VoidType(),
mlir::ValueRange operands = mlir::ValueRange(),
[[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) {
assert(!cir::MissingFeatures::opCallCallConv());
assert(!cir::MissingFeatures::opCallSideEffect());
return createCallOp(loc, callee, returnType, operands);
}

cir::CallOp createTryCallOp(
mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands,
[[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) {
assert(!cir::MissingFeatures::opCallCallConv());
assert(!cir::MissingFeatures::opCallSideEffect());
return createTryCallOp(loc, mlir::SymbolRefAttr::get(callee),
callee.getFunctionType().getReturnType(), operands);
}

//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct MissingFeatures {
static bool opFuncNoReturn() { return false; }
static bool setFunctionAttributes() { return false; }
static bool setLLVMFunctionFEnvAttributes() { return false; }
static bool setFunctionPersonality() { return false; }

// CallOp handling
static bool opCallAggregateArgs() { return false; }
Expand Down Expand Up @@ -334,6 +335,9 @@ struct MissingFeatures {
static bool vtableRelativeLayout() { return false; }
static bool weakRefReference() { return false; }
static bool writebacks() { return false; }
static bool msvcCXXPersonality() { return false; }
static bool functionUsesSEHTry() { return false; }
static bool nothrowAttr() { return false; }

// Missing types
static bool dataMemberType() { return false; }
Expand All @@ -349,7 +353,6 @@ struct MissingFeatures {
static bool awaitOp() { return false; }
static bool callOp() { return false; }
static bool ifOp() { return false; }
static bool invokeOp() { return false; }
static bool labelOp() { return false; }
static bool ptrDiffOp() { return false; }
static bool llvmLoweringPtrDiffConsidersPointee() { return false; }
Expand All @@ -359,6 +362,7 @@ struct MissingFeatures {
static bool tryOp() { return false; }
static bool vecTernaryOp() { return false; }
static bool zextOp() { return false; }
static bool catchParamOp() { return false; }

// Future CIR attributes
static bool optInfoAttr() { return false; }
Expand Down
50 changes: 45 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,12 +465,47 @@ static cir::CIRCallOpInterface
emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal,
cir::FuncOp directFuncOp,
const SmallVectorImpl<mlir::Value> &cirCallArgs,
const SmallVectorImpl<mlir::Value> &cirCallArgs, bool isInvoke,
const mlir::NamedAttrList &attrs) {
CIRGenBuilderTy &builder = cgf.getBuilder();

assert(!cir::MissingFeatures::opCallSurroundingTry());
assert(!cir::MissingFeatures::invokeOp());

if (isInvoke) {
// This call may throw and requires catch and/or cleanup handling.
// If this call does not appear within the `try` region of an existing
// TryOp, we must create a synthetic TryOp to contain the call. This
// happens when a call that may throw appears within a cleanup
// scope.

// In OG, we build the landing pad for this scope. In CIR, we emit a
// synthetic cir.try because this didn't come from code generating from a
// try/catch in C++.
assert(cgf.curLexScope && "expected scope");
cir::TryOp tryOp = cgf.curLexScope->getClosestTryParent();
if (!tryOp) {
cgf.cgm.errorNYI(
"emitCallLikeOp: call does not have an associated cir.try");
return {};
}

if (tryOp.getSynthetic()) {
cgf.cgm.errorNYI("emitCallLikeOp: tryOp synthetic");
return {};
}

cir::CallOp callOpWithExceptions;
if (indirectFuncTy) {
cgf.cgm.errorNYI("emitCallLikeOp: indirect function type");
return {};
}

callOpWithExceptions =
builder.createCallOp(callLoc, directFuncOp, cirCallArgs);

cgf.populateCatchHandlersIfRequired(tryOp);
return callOpWithExceptions;
}

assert(builder.getInsertionBlock() && "expected valid basic block");

Expand Down Expand Up @@ -601,8 +636,6 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
assert(!cir::MissingFeatures::opCallAttrs());
cgm.constructAttributeList(callee.getAbstractInfo(), attrs);

assert(!cir::MissingFeatures::invokeOp());

cir::FuncType indirectFuncTy;
mlir::Value indirectFuncVal;
cir::FuncOp directFuncOp;
Expand All @@ -628,10 +661,17 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
indirectFuncVal = calleePtr->getResult(0);
}

assert(!cir::MissingFeatures::msvcCXXPersonality());
assert(!cir::MissingFeatures::functionUsesSEHTry());
assert(!cir::MissingFeatures::nothrowAttr());

bool cannotThrow = attrs.getNamed("nothrow").has_value();
bool isInvoke = !cannotThrow && isCatchOrCleanupRequired();

mlir::Location callLoc = loc;
cir::CIRCallOpInterface theCall =
emitCallLikeOp(*this, loc, indirectFuncTy, indirectFuncVal, directFuncOp,
cirCallArgs, attrs);
cirCallArgs, isInvoke, attrs);

if (callOp)
*callOp = theCall;
Expand Down
15 changes: 14 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,22 @@ void EHScopeStack::popCleanup() {
}
}

bool EHScopeStack::requiresCatchOrCleanup() const {
for (stable_iterator si = getInnermostEHScope(); si != stable_end();) {
if (auto *cleanup = dyn_cast<EHCleanupScope>(&*find(si))) {
if (cleanup->isLifetimeMarker()) {
// Skip lifetime markers and continue from the enclosing EH scope
assert(!cir::MissingFeatures::emitLifetimeMarkers());
continue;
}
}
return true;
}
return false;
}

EHCatchScope *EHScopeStack::pushCatch(unsigned numHandlers) {
char *buffer = allocate(EHCatchScope::getSizeForNumHandlers(numHandlers));
assert(!cir::MissingFeatures::innermostEHScope());
EHCatchScope *scope =
new (buffer) EHCatchScope(numHandlers, innermostEHScope);
innermostEHScope = stable_begin();
Expand Down
22 changes: 17 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenCleanup.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "CIRGenModule.h"
#include "EHScopeStack.h"
#include "mlir/IR/Value.h"
#include "clang/AST/StmtCXX.h"

namespace clang::CIRGen {

Expand All @@ -38,6 +39,8 @@ class EHScope {
};
enum { NumCommonBits = 3 };

bool scopeMayThrow;

protected:
class CatchBitFields {
friend class EHCatchScope;
Expand Down Expand Up @@ -92,10 +95,11 @@ class EHScope {
// Traditional LLVM codegen also checks for `!block->use_empty()`, but
// in CIRGen the block content is not important, just used as a way to
// signal `hasEHBranches`.
assert(!cir::MissingFeatures::ehstackBranches());
return false;
return scopeMayThrow;
}

void setMayThrow(bool mayThrow) { scopeMayThrow = mayThrow; }

EHScopeStack::stable_iterator getEnclosingEHScope() const {
return enclosingEHScope;
}
Expand All @@ -121,6 +125,9 @@ class EHCatchScope : public EHScope {
/// The catch handler for this type.
mlir::Region *region;

/// The catch handler stmt.
const CXXCatchStmt *stmt;

bool isCatchAll() const { return type.rtti == nullptr; }
};

Expand All @@ -147,10 +154,13 @@ class EHCatchScope : public EHScope {

unsigned getNumHandlers() const { return catchBits.numHandlers; }

void setHandler(unsigned i, CatchTypeInfo type, mlir::Region *region) {
void setHandler(unsigned i, CatchTypeInfo type, mlir::Region *region,
const CXXCatchStmt *stmt) {
assert(i < getNumHandlers());
getHandlers()[i].type = type;
getHandlers()[i].region = region;
Handler *handler = &getHandlers()[i];
handler->type = type;
handler->region = region;
handler->stmt = stmt;
}

const Handler &getHandler(unsigned i) const {
Expand Down Expand Up @@ -231,6 +241,8 @@ class alignas(EHScopeStack::ScopeStackAlignment) EHCleanupScope
bool isActive() const { return cleanupBits.isActive; }
void setActive(bool isActive) { cleanupBits.isActive = isActive; }

bool isLifetimeMarker() const { return cleanupBits.isLifetimeMarker; }

unsigned getFixupDepth() const { return fixupDepth; }
EHScopeStack::stable_iterator getEnclosingNormalCleanup() const {
return enclosingNormal;
Expand Down
Loading
Loading