@@ -888,6 +888,69 @@ 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+ mlir::OperandRange argOps = call.getArgs ();
908+ mlir::ArrayRef<mlir::Type> funcArgTypes =
909+ newF.getFunctionType ().getInputs ();
910+ // In the case of variadic functions, the call may have more arguments that
911+ // the function type, so we can't use llvm::enumerate here.
912+ for (unsigned i = 0 ; i < funcArgTypes.size (); i++) {
913+ if (argOps[i].getType () == funcArgTypes[i])
914+ continue ;
915+
916+ // The purpose of this entire function is to insert bitcasts in the case
917+ // where these types don't match, but I haven't seen a case where that
918+ // happens.
919+ errorNYI (call.getLoc (), " replace call with mismatched types" );
920+ }
921+ }
922+ }
923+
924+ void CIRGenModule::applyReplacements () {
925+ for (auto &i : replacements) {
926+ StringRef mangledName = i.first ();
927+ mlir::Operation *replacement = i.second ;
928+ mlir::Operation *entry = getGlobalValue (mangledName);
929+ if (!entry)
930+ continue ;
931+ assert (isa<cir::FuncOp>(entry) && " expected function" );
932+ auto oldF = cast<cir::FuncOp>(entry);
933+ auto newF = dyn_cast<cir::FuncOp>(replacement);
934+ if (!newF) {
935+ // In classic codegen, this can be a global alias, a bitcast, or a GEP.
936+ errorNYI (replacement->getLoc (), " replacement is not a function" );
937+ continue ;
938+ }
939+
940+ // LLVM has opaque pointer but CIR not. So we may have to handle these
941+ // different pointer types when performing replacement.
942+ replacePointerTypeArgs (oldF, newF);
943+
944+ // Replace old with new, but keep the old order.
945+ if (oldF.replaceAllSymbolUses (newF.getSymNameAttr (), theModule).failed ())
946+ llvm_unreachable (" internal error, cannot RAUW symbol" );
947+ if (newF) {
948+ newF->moveBefore (oldF);
949+ oldF->erase ();
950+ }
951+ }
952+ }
953+
891954// TODO(CIR): this could be a common method between LLVM codegen.
892955static bool isVarDeclStrongDefinition (const ASTContext &astContext,
893956 CIRGenModule &cgm, const VarDecl *vd,
@@ -1797,11 +1860,52 @@ CIRGenModule::getGlobalVisibilityAttrFromDecl(const Decl *decl) {
17971860
17981861void CIRGenModule::release () {
17991862 emitDeferred ();
1863+ applyReplacements ();
18001864
18011865 // There's a lot of code that is not implemented yet.
18021866 assert (!cir::MissingFeatures::cgmRelease ());
18031867}
18041868
1869+ void CIRGenModule::emitAliasForGlobal (StringRef mangledName,
1870+ mlir::Operation *op, GlobalDecl aliasGD,
1871+ cir::FuncOp aliasee,
1872+ cir::GlobalLinkageKind linkage) {
1873+
1874+ auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.getDecl ());
1875+ assert (aliasFD && " expected FunctionDecl" );
1876+
1877+ // The aliasee function type is different from the alias one, this difference
1878+ // is specific to CIR because in LLVM the ptr types are already erased at this
1879+ // point.
1880+ const CIRGenFunctionInfo &fnInfo =
1881+ getTypes ().arrangeCXXStructorDeclaration (aliasGD);
1882+ cir::FuncType fnType = getTypes ().getFunctionType (fnInfo);
1883+
1884+ cir::FuncOp alias =
1885+ createCIRFunction (getLoc (aliasGD.getDecl ()->getSourceRange ()),
1886+ mangledName, fnType, aliasFD);
1887+ alias.setAliasee (aliasee.getName ());
1888+ alias.setLinkage (linkage);
1889+ // Declarations cannot have public MLIR visibility, just mark them private
1890+ // but this really should have no meaning since CIR should not be using
1891+ // this information to derive linkage information.
1892+ mlir::SymbolTable::setSymbolVisibility (
1893+ alias, mlir::SymbolTable::Visibility::Private);
1894+
1895+ // Alias constructors and destructors are always unnamed_addr.
1896+ assert (!cir::MissingFeatures::opGlobalUnnamedAddr ());
1897+
1898+ // Switch any previous uses to the alias.
1899+ if (op) {
1900+ errorNYI (aliasFD->getSourceRange (), " emitAliasForGlobal: previous uses" );
1901+ } else {
1902+ // Name already set by createCIRFunction
1903+ }
1904+
1905+ // Finally, set up the alias with its proper name and attributes.
1906+ setCommonAttributes (aliasGD, alias);
1907+ }
1908+
18051909mlir::Type CIRGenModule::convertType (QualType type) {
18061910 return genTypes.convertType (type);
18071911}
0 commit comments