madanial updated this revision to Diff 492312.
madanial retitled this revision from "[Flang] Add user option 
-funderscoring/-fnounderscoring to enable/disable ExternalNameConversionPass" 
to "[Flang] Add user option -funderscoring/-fnounderscoring to control trailing 
underscore added to external names".
madanial edited the summary of this revision.
madanial added a comment.
Herald added a reviewer: sscalpone.
Herald added subscribers: sunshaoce, mehdi_amini.

Implementing functionality to control just the trailing underscore for external 
names to achieve similar functionality to the option in gfortran, as well as 
rebase and address review comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140795/new/

https://reviews.llvm.org/D140795

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Flang.cpp
  flang/include/flang/Frontend/CodeGenOptions.def
  flang/include/flang/Optimizer/Transforms/Passes.h
  flang/include/flang/Optimizer/Transforms/Passes.td
  flang/include/flang/Tools/CLOptions.inc
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendActions.cpp
  flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp
  flang/test/Driver/driver-help-hidden.f90
  flang/test/Driver/driver-help.f90
  flang/test/Driver/underscoring.f90

Index: flang/test/Driver/underscoring.f90
===================================================================
--- /dev/null
+++ flang/test/Driver/underscoring.f90
@@ -0,0 +1,24 @@
+! Test the -funderscoring flag
+
+! RUN: %flang_fc1 -S %s -o - 2>&1 | FileCheck %s --check-prefix=UNDERSCORING
+! RUN: %flang_fc1 -S -fno-underscoring %s -o - 2>&1 | FileCheck %s --check-prefix=NO-UNDERSCORING
+
+subroutine test()
+  common /comblk/ a, b
+  external :: ext_sub
+  call ext_sub()
+end
+
+! UNDERSCORING: test_
+! UNDERSCORING: ext_sub_
+! UNDERSCORING: comblk_
+
+! NO-UNDERSCORING-NOT: test_
+! NO-UNDERSCORING-NOT: _QPtest
+! NO-UNDERSCORING: test
+! NO-UNDERSCORING-NOT: ext_sub_
+! NO-UNDERSCORING-NOT: _QPext_sub
+! NO-UNDERSCORING: ext_sub
+! NO-UNDERSCORING-NOT: comblk_
+! NO-UNDERSCORING-NOT: _QBcomblk
+! NO-UNDERSCORING: comblk
Index: flang/test/Driver/driver-help.f90
===================================================================
--- flang/test/Driver/driver-help.f90
+++ flang/test/Driver/driver-help.f90
@@ -50,6 +50,7 @@
 ! HELP-NEXT: -fpass-plugin=<dsopath> Load pass plugin from a dynamic shared object file (only with new pass manager).
 ! HELP-NEXT: -freciprocal-math      Allow division operations to be reassociated
 ! HELP-NEXT: -fsyntax-only          Run the preprocessor, parser and semantic analysis stages
+! HELP-NEXT: -funderscoring         Appends one trailing underscore to external names
 ! HELP-NEXT: -fxor-operator         Enable .XOR. as a synonym of .NEQV.
 ! HELP-NEXT: -help                  Display available options
 ! HELP-NEXT: -I <dir>               Add directory to the end of the list of include search paths
@@ -135,6 +136,7 @@
 ! HELP-FC1-NEXT: -fpass-plugin=<dsopath> Load pass plugin from a dynamic shared object file (only with new pass manager).
 ! HELP-FC1-NEXT: -freciprocal-math      Allow division operations to be reassociated
 ! HELP-FC1-NEXT: -fsyntax-only          Run the preprocessor, parser and semantic analysis stages
+! HELP-FC1-NEXT: -funderscoring         Appends one trailing underscore to external names
 ! HELP-FC1-NEXT: -fxor-operator         Enable .XOR. as a synonym of .NEQV.
 ! HELP-FC1-NEXT: -help                  Display available options
 ! HELP-FC1-NEXT: -init-only             Only execute frontend initialization
Index: flang/test/Driver/driver-help-hidden.f90
===================================================================
--- flang/test/Driver/driver-help-hidden.f90
+++ flang/test/Driver/driver-help-hidden.f90
@@ -52,6 +52,7 @@
 ! CHECK-NEXT: -fpass-plugin=<dsopath> Load pass plugin from a dynamic shared object file (only with new pass manager).
 ! CHECK-NEXT: -freciprocal-math      Allow division operations to be reassociated
 ! CHECK-NEXT: -fsyntax-only          Run the preprocessor, parser and semantic analysis stages
+! CHECK-NEXT: -funderscoring         Appends one trailing underscore to external names
 ! CHECK-NEXT: -fxor-operator         Enable .XOR. as a synonym of .NEQV.
 ! CHECK-NEXT: -help     Display available options
 ! CHECK-NEXT: -I <dir>               Add directory to the end of the list of include search paths
Index: flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp
===================================================================
--- flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp
+++ flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp
@@ -32,11 +32,17 @@
 std::string
 mangleExternalName(const std::pair<fir::NameUniquer::NameKind,
                                    fir::NameUniquer::DeconstructedName>
-                       result) {
+                       result,
+                   bool appendUnderscore) {
   if (result.first == fir::NameUniquer::NameKind::COMMON &&
       result.second.name.empty())
     return "__BLNK__";
-  return result.second.name + "_";
+
+  std::string newName{result.second.name};
+  if (appendUnderscore)
+    newName = newName + "_";
+
+  return newName;
 }
 
 //===----------------------------------------------------------------------===//
@@ -49,6 +55,10 @@
 public:
   using OpRewritePattern::OpRewritePattern;
 
+  MangleNameOnCallOp(mlir::MLIRContext *ctx, bool appendUnderscore)
+      : mlir::OpRewritePattern<fir::CallOp>(ctx),
+        appendUnderscore(appendUnderscore) {}
+
   mlir::LogicalResult
   matchAndRewrite(fir::CallOp op,
                   mlir::PatternRewriter &rewriter) const override {
@@ -58,34 +68,49 @@
       auto result =
           fir::NameUniquer::deconstruct(callee->getRootReference().getValue());
       if (fir::NameUniquer::isExternalFacingUniquedName(result))
-        op.setCalleeAttr(
-            SymbolRefAttr::get(op.getContext(), mangleExternalName(result)));
+        op.setCalleeAttr(SymbolRefAttr::get(
+            op.getContext(), mangleExternalName(result, appendUnderscore)));
     }
     rewriter.finalizeRootUpdate(op);
     return success();
   }
+
+private:
+  bool appendUnderscore;
 };
 
 struct MangleNameOnFuncOp : public mlir::OpRewritePattern<mlir::func::FuncOp> {
 public:
   using OpRewritePattern::OpRewritePattern;
 
+  MangleNameOnFuncOp(mlir::MLIRContext *ctx, bool appendUnderscore)
+      : mlir::OpRewritePattern<mlir::func::FuncOp>(ctx),
+        appendUnderscore(appendUnderscore) {}
+
   mlir::LogicalResult
   matchAndRewrite(mlir::func::FuncOp op,
                   mlir::PatternRewriter &rewriter) const override {
     rewriter.startRootUpdate(op);
     auto result = fir::NameUniquer::deconstruct(op.getSymName());
     if (fir::NameUniquer::isExternalFacingUniquedName(result))
-      op.setSymNameAttr(rewriter.getStringAttr(mangleExternalName(result)));
+      op.setSymNameAttr(
+          rewriter.getStringAttr(mangleExternalName(result, appendUnderscore)));
     rewriter.finalizeRootUpdate(op);
     return success();
   }
+
+private:
+  bool appendUnderscore;
 };
 
 struct MangleNameForCommonBlock : public mlir::OpRewritePattern<fir::GlobalOp> {
 public:
   using OpRewritePattern::OpRewritePattern;
 
+  MangleNameForCommonBlock(mlir::MLIRContext *ctx, bool appendUnderscore)
+      : mlir::OpRewritePattern<fir::GlobalOp>(ctx),
+        appendUnderscore(appendUnderscore) {}
+
   mlir::LogicalResult
   matchAndRewrite(fir::GlobalOp op,
                   mlir::PatternRewriter &rewriter) const override {
@@ -93,39 +118,55 @@
     auto result = fir::NameUniquer::deconstruct(
         op.getSymref().getRootReference().getValue());
     if (fir::NameUniquer::isExternalFacingUniquedName(result)) {
-      auto newName = mangleExternalName(result);
+      auto newName = mangleExternalName(result, appendUnderscore);
       op.setSymrefAttr(mlir::SymbolRefAttr::get(op.getContext(), newName));
       SymbolTable::setSymbolName(op, newName);
     }
     rewriter.finalizeRootUpdate(op);
     return success();
   }
+
+private:
+  bool appendUnderscore;
 };
 
 struct MangleNameOnAddrOfOp : public mlir::OpRewritePattern<fir::AddrOfOp> {
 public:
   using OpRewritePattern::OpRewritePattern;
 
+  MangleNameOnAddrOfOp(mlir::MLIRContext *ctx, bool appendUnderscore)
+      : mlir::OpRewritePattern<fir::AddrOfOp>(ctx),
+        appendUnderscore(appendUnderscore) {}
+
   mlir::LogicalResult
   matchAndRewrite(fir::AddrOfOp op,
                   mlir::PatternRewriter &rewriter) const override {
     auto result = fir::NameUniquer::deconstruct(
         op.getSymbol().getRootReference().getValue());
     if (fir::NameUniquer::isExternalFacingUniquedName(result)) {
-      auto newName =
-          SymbolRefAttr::get(op.getContext(), mangleExternalName(result));
+      auto newName = SymbolRefAttr::get(
+          op.getContext(), mangleExternalName(result, appendUnderscore));
       rewriter.replaceOpWithNewOp<fir::AddrOfOp>(op, op.getResTy().getType(),
                                                  newName);
     }
     return success();
   }
+
+private:
+  bool appendUnderscore;
 };
 
 class ExternalNameConversionPass
     : public fir::impl::ExternalNameConversionBase<ExternalNameConversionPass> {
 public:
+  ExternalNameConversionPass(bool appendUnderscore)
+      : appendUnderscore(appendUnderscore) {}
+
   mlir::ModuleOp getModule() { return getOperation(); }
   void runOnOperation() override;
+
+private:
+  bool appendUnderscore;
 };
 } // namespace
 
@@ -135,7 +176,8 @@
 
   mlir::RewritePatternSet patterns(context);
   patterns.insert<MangleNameOnCallOp, MangleNameOnCallOp, MangleNameOnFuncOp,
-                  MangleNameForCommonBlock, MangleNameOnAddrOfOp>(context);
+                  MangleNameForCommonBlock, MangleNameOnAddrOfOp>(
+      context, appendUnderscore);
 
   ConversionTarget target(*context);
   target.addLegalDialect<fir::FIROpsDialect, LLVM::LLVMDialect,
@@ -166,6 +208,7 @@
     signalPassFailure();
 }
 
-std::unique_ptr<mlir::Pass> fir::createExternalNameConversionPass() {
-  return std::make_unique<ExternalNameConversionPass>();
+std::unique_ptr<mlir::Pass>
+fir::createExternalNameConversionPass(bool appendUnderscore) {
+  return std::make_unique<ExternalNameConversionPass>(appendUnderscore);
 }
Index: flang/lib/Frontend/FrontendActions.cpp
===================================================================
--- flang/lib/Frontend/FrontendActions.cpp
+++ flang/lib/Frontend/FrontendActions.cpp
@@ -532,6 +532,7 @@
   auto opts = ci.getInvocation().getCodeGenOpts();
   llvm::OptimizationLevel level = mapToLevel(opts);
 
+  auto Underscoring = opts.Underscoring;
   fir::support::loadDialects(*mlirCtx);
   fir::support::registerLLVMTranslation(*mlirCtx);
 
@@ -543,7 +544,7 @@
   pm.enableVerifier(/*verifyPasses=*/true);
 
   // Create the pass pipeline
-  fir::createMLIRToLLVMPassPipeline(pm, level);
+  fir::createMLIRToLLVMPassPipeline(pm, level, Underscoring);
   mlir::applyPassManagerCLOptions(pm);
 
   // run the pass manager
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- flang/lib/Frontend/CompilerInvocation.cpp
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -161,6 +161,12 @@
     if (args.hasArg(clang::driver::options::OPT_pic_is_pie))
       opts.IsPIE = 1;
   }
+
+  // This option is compatible with -f[no-]underscoring in gfortran.
+  if (args.hasFlag(clang::driver::options::OPT_fno_underscoring,
+                   clang::driver::options::OPT_funderscoring, false)) {
+    opts.Underscoring = 0;
+  }
 }
 
 /// Parses all target input arguments and populates the target
Index: flang/include/flang/Tools/CLOptions.inc
===================================================================
--- flang/include/flang/Tools/CLOptions.inc
+++ flang/include/flang/Tools/CLOptions.inc
@@ -157,9 +157,11 @@
 }
 #endif
 
-inline void addExternalNameConversionPass(mlir::PassManager &pm) {
-  addPassConditionally(pm, disableExternalNameConversion,
-      [&]() { return fir::createExternalNameConversionPass(); });
+inline void addExternalNameConversionPass(
+    mlir::PassManager &pm, bool appendUnderscore = true) {
+  addPassConditionally(pm, disableExternalNameConversion, [&]() {
+    return fir::createExternalNameConversionPass(appendUnderscore);
+  });
 }
 
 /// Create a pass pipeline for running default optimization passes for
@@ -202,8 +204,9 @@
 }
 
 #if !defined(FLANG_EXCLUDE_CODEGEN)
-inline void createDefaultFIRCodeGenPassPipeline(
-    mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel) {
+inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
+    llvm::OptimizationLevel optLevel = defaultOptLevel,
+    bool Underscoring = true) {
   fir::addBoxedProcedurePass(pm);
   pm.addNestedPass<mlir::func::FuncOp>(
       fir::createAbstractResultOnFuncOptPass());
@@ -211,8 +214,8 @@
       fir::createAbstractResultOnGlobalOptPass());
   fir::addCodeGenRewritePass(pm);
   fir::addTargetRewritePass(pm);
-  fir::addExternalNameConversionPass(pm);
-  fir::addFIRToLLVMPass(pm, optLevel);
+  fir::addExternalNameConversionPass(pm, Underscoring);
+  fir::addFIRToLLVMPass(pm);
 }
 
 /// Create a pass pipeline for lowering from MLIR to LLVM IR
@@ -220,13 +223,14 @@
 /// \param pm - MLIR pass manager that will hold the pipeline definition
 /// \param optLevel - optimization level used for creating FIR optimization
 ///   passes pipeline
-inline void createMLIRToLLVMPassPipeline(
-    mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel) {
+inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
+    llvm::OptimizationLevel optLevel = defaultOptLevel,
+    bool Underscoring = true) {
   // Add default optimizer pass pipeline.
   fir::createDefaultFIROptimizerPassPipeline(pm, optLevel);
 
   // Add codegen pass pipeline.
-  fir::createDefaultFIRCodeGenPassPipeline(pm, optLevel);
+  fir::createDefaultFIRCodeGenPassPipeline(pm, optLevel, Underscoring);
 }
 #undef FLANG_EXCLUDE_CODEGEN
 #endif
Index: flang/include/flang/Optimizer/Transforms/Passes.td
===================================================================
--- flang/include/flang/Optimizer/Transforms/Passes.td
+++ flang/include/flang/Optimizer/Transforms/Passes.td
@@ -169,6 +169,11 @@
     Demangle FIR internal name and mangle them for external interoperability.
   }];
   let constructor = "::fir::createExternalNameConversionPass()";
+  let options = [
+    Option<"appendUnderscore", "append-underscore",
+           "bool", /*default=*/"true",
+           "Append trailing underscore to external names.">
+  ];
 }
 
 def MemRefDataFlowOpt : Pass<"fir-memref-dataflow-opt", "::mlir::func::FuncOp"> {
Index: flang/include/flang/Optimizer/Transforms/Passes.h
===================================================================
--- flang/include/flang/Optimizer/Transforms/Passes.h
+++ flang/include/flang/Optimizer/Transforms/Passes.h
@@ -51,7 +51,8 @@
 createArrayValueCopyPass(fir::ArrayValueCopyOptions options = {});
 std::unique_ptr<mlir::Pass> createFirToCfgPass();
 std::unique_ptr<mlir::Pass> createCharacterConversionPass();
-std::unique_ptr<mlir::Pass> createExternalNameConversionPass();
+std::unique_ptr<mlir::Pass>
+createExternalNameConversionPass(bool appendUnderscore = true);
 std::unique_ptr<mlir::Pass> createMemDataFlowOptPass();
 std::unique_ptr<mlir::Pass> createPromoteToAffinePass();
 std::unique_ptr<mlir::Pass> createMemoryAllocationPass();
Index: flang/include/flang/Frontend/CodeGenOptions.def
===================================================================
--- flang/include/flang/Frontend/CodeGenOptions.def
+++ flang/include/flang/Frontend/CodeGenOptions.def
@@ -27,6 +27,7 @@
 CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module.
 CODEGENOPT(IsPIE, 1, 0) ///< PIE level is the same as PIC Level.
 
+CODEGENOPT(Underscoring, 1, 1)
 ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use.
 
 #undef CODEGENOPT
Index: clang/lib/Driver/ToolChains/Flang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Flang.cpp
+++ clang/lib/Driver/ToolChains/Flang.cpp
@@ -56,7 +56,8 @@
                   {options::OPT_module_dir, options::OPT_fdebug_module_writer,
                    options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
                    options::OPT_std_EQ, options::OPT_W_Joined,
-                   options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ});
+                   options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ,
+                   options::OPT_funderscoring, options::OPT_fno_underscoring});
 }
 
 void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4982,7 +4982,6 @@
 defm second_underscore : BooleanFFlag<"second-underscore">, Group<gfortran_Group>;
 defm sign_zero : BooleanFFlag<"sign-zero">, Group<gfortran_Group>;
 defm stack_arrays : BooleanFFlag<"stack-arrays">, Group<gfortran_Group>;
-defm underscoring : BooleanFFlag<"underscoring">, Group<gfortran_Group>;
 defm whole_file : BooleanFFlag<"whole-file">, Group<gfortran_Group>;
 
 // C++ SYCL options
@@ -5057,6 +5056,7 @@
 defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">;
 defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">;
 defm implicit_none : OptInFC1FFlag<"implicit-none", "No implicit typing allowed unless overridden by IMPLICIT statements">;
+defm underscoring : OptInFC1FFlag<"underscoring", "Appends one trailing underscore to external names">;
 
 def fno_automatic : Flag<["-"], "fno-automatic">, Group<f_Group>,
   HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to