@@ -888,6 +888,65 @@ void CIRGenModule::updateCompletedType(const TagDecl *td) {
888888 genTypes.updateCompletedType (td);
889889}
890890
891+ void CIRGenModule::addReplacement (StringRef name, mlir::Operation *op) {
892+ replacements[name] = op;
893+ }
894+
895+ void CIRGenModule::replacePointerTypeArgs (cir::FuncOp oldF, cir::FuncOp newF) {
896+ std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
897+ oldF.getSymbolUses (theModule);
898+ if (!optionalUseRange)
899+ return ;
900+
901+ for (const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
902+ // CallTryOp only shows up after FlattenCFG.
903+ auto call = mlir::dyn_cast<cir::CallOp>(u.getUser ());
904+ if (!call)
905+ continue ;
906+
907+ for (const auto [argOp, fnArgType] :
908+ llvm::zip (call.getArgs (), newF.getFunctionType ().getInputs ())) {
909+ if (argOp.getType () == fnArgType)
910+ continue ;
911+
912+ // The purpose of this entire function is to insert bitcasts in the case
913+ // where these types don't match, but I haven't seen a case where that
914+ // happens.
915+ errorNYI (call.getLoc (), " replace call with mismatched types" );
916+ }
917+ }
918+ }
919+
920+ void CIRGenModule::applyReplacements () {
921+ for (auto &i : replacements) {
922+ StringRef mangledName = i.first ();
923+ mlir::Operation *replacement = i.second ;
924+ mlir::Operation *entry = getGlobalValue (mangledName);
925+ if (!entry)
926+ continue ;
927+ assert (isa<cir::FuncOp>(entry) && " expected function" );
928+ auto oldF = cast<cir::FuncOp>(entry);
929+ auto newF = dyn_cast<cir::FuncOp>(replacement);
930+ if (!newF) {
931+ // In classic codegen, this can be a global alias, a bitcast, or a GEP.
932+ errorNYI (replacement->getLoc (), " replacement is not a function" );
933+ continue ;
934+ }
935+
936+ // LLVM has opaque pointer but CIR not. So we may have to handle these
937+ // different pointer types when performing replacement.
938+ replacePointerTypeArgs (oldF, newF);
939+
940+ // Replace old with new, but keep the old order.
941+ if (oldF.replaceAllSymbolUses (newF.getSymNameAttr (), theModule).failed ())
942+ llvm_unreachable (" internal error, cannot RAUW symbol" );
943+ if (newF) {
944+ newF->moveBefore (oldF);
945+ oldF->erase ();
946+ }
947+ }
948+ }
949+
891950// TODO(CIR): this could be a common method between LLVM codegen.
892951static bool isVarDeclStrongDefinition (const ASTContext &astContext,
893952 CIRGenModule &cgm, const VarDecl *vd,
@@ -1797,11 +1856,52 @@ CIRGenModule::getGlobalVisibilityAttrFromDecl(const Decl *decl) {
17971856
17981857void CIRGenModule::release () {
17991858 emitDeferred ();
1859+ applyReplacements ();
18001860
18011861 // There's a lot of code that is not implemented yet.
18021862 assert (!cir::MissingFeatures::cgmRelease ());
18031863}
18041864
1865+ void CIRGenModule::emitAliasForGlobal (StringRef mangledName,
1866+ mlir::Operation *op, GlobalDecl aliasGD,
1867+ cir::FuncOp aliasee,
1868+ cir::GlobalLinkageKind linkage) {
1869+
1870+ auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.getDecl ());
1871+ assert (aliasFD && " expected FunctionDecl" );
1872+
1873+ // The aliasee function type is different from the alias one, this difference
1874+ // is specific to CIR because in LLVM the ptr types are already erased at this
1875+ // point.
1876+ const CIRGenFunctionInfo &fnInfo =
1877+ getTypes ().arrangeCXXStructorDeclaration (aliasGD);
1878+ cir::FuncType fnType = getTypes ().getFunctionType (fnInfo);
1879+
1880+ cir::FuncOp alias =
1881+ createCIRFunction (getLoc (aliasGD.getDecl ()->getSourceRange ()),
1882+ mangledName, fnType, aliasFD);
1883+ alias.setAliasee (aliasee.getName ());
1884+ alias.setLinkage (linkage);
1885+ // Declarations cannot have public MLIR visibility, just mark them private
1886+ // but this really should have no meaning since CIR should not be using
1887+ // this information to derive linkage information.
1888+ mlir::SymbolTable::setSymbolVisibility (
1889+ alias, mlir::SymbolTable::Visibility::Private);
1890+
1891+ // Alias constructors and destructors are always unnamed_addr.
1892+ assert (!cir::MissingFeatures::opGlobalUnnamedAddr ());
1893+
1894+ // Switch any previous uses to the alias.
1895+ if (op) {
1896+ errorNYI (aliasFD->getSourceRange (), " emitAliasForGlobal: previous uses" );
1897+ } else {
1898+ // Name already set by createCIRFunction
1899+ }
1900+
1901+ // Finally, set up the alias with its proper name and attributes.
1902+ setCommonAttributes (aliasGD, alias);
1903+ }
1904+
18051905mlir::Type CIRGenModule::convertType (QualType type) {
18061906 return genTypes.convertType (type);
18071907}
0 commit comments