================ @@ -149,14 +156,125 @@ void CIRGenFunction::declare(mlir::Value addrVal, const Decl *var, QualType ty, allocaOp.setConstantAttr(mlir::UnitAttr::get(&getMLIRContext())); } +void CIRGenFunction::LexicalScope::cleanup() { + CIRGenBuilderTy &builder = cgf.builder; + LexicalScope *localScope = cgf.currLexScope; + + if (returnBlock != nullptr) { + // Write out the return block, which loads the value from `__retval` and + // issues the `cir.return`. + mlir::OpBuilder::InsertionGuard guard(builder); + builder.setInsertionPointToEnd(returnBlock); + (void)emitReturn(*returnLoc); + } + + mlir::Block *currBlock = builder.getBlock(); + if (isGlobalInit() && !currBlock) + return; + if (currBlock->mightHaveTerminator() && currBlock->getTerminator()) + return; + + // Get rid of any empty block at the end of the scope. + bool entryBlock = builder.getInsertionBlock()->isEntryBlock(); + if (!entryBlock && currBlock->empty()) { + currBlock->erase(); + if (returnBlock != nullptr && returnBlock->getUses().empty()) + returnBlock->erase(); + return; + } + + // Reached the end of the scope. + { + mlir::OpBuilder::InsertionGuard guard(builder); + builder.setInsertionPointToEnd(currBlock); + + if (localScope->depth == 0) { + // Reached the end of the function. + if (returnBlock != nullptr) { + if (returnBlock->getUses().empty()) + returnBlock->erase(); + else { + builder.create<cir::BrOp>(*returnLoc, returnBlock); + return; + } + } + emitImplicitReturn(); + return; + } + // Reached the end of a non-function scope. Some scopes, such as those + // used with the ?: operator, can return a value. + if (!localScope->isTernary() && !currBlock->mightHaveTerminator()) { + !retVal ? builder.create<cir::YieldOp>(localScope->endLoc) + : builder.create<cir::YieldOp>(localScope->endLoc, retVal); + } + } +} + +cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) { + CIRGenBuilderTy &builder = cgf.getBuilder(); + + if (!cgf.curFn.getFunctionType().hasVoidReturn()) { + // Load the value from `__retval` and return it via the `cir.return` op. + auto value = builder.create<cir::LoadOp>( + loc, cgf.curFn.getFunctionType().getReturnType(), *cgf.fnRetAlloca); + return builder.create<cir::ReturnOp>(loc, + llvm::ArrayRef(value.getResult())); + } + return builder.create<cir::ReturnOp>(loc); +} + +// This is copyied from CodeGenModule::MayDropFunctionReturn. This is a ---------------- erichkeane wrote:
```suggestion // This is copied from CodeGenModule::MayDropFunctionReturn. This is a ``` https://github.com/llvm/llvm-project/pull/131945 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits