https://github.com/kaviya2510 updated https://github.com/llvm/llvm-project/pull/216680
>From 0f00a4d07fc599511bfb821731f32d5449c08e54 Mon Sep 17 00:00:00 2001 From: Kaviya Rajendiran <[email protected]> Date: Mon, 17 Aug 2026 15:31:44 +0530 Subject: [PATCH 1/3] [Flang][Driver] Added support for -funique-internal-linkage-names --- clang/include/clang/Options/Options.td | 4 +-- clang/lib/Driver/ToolChains/Flang.cpp | 3 +++ .../include/flang/Frontend/CodeGenOptions.def | 1 + flang/include/flang/Lower/Bridge.h | 4 +++ .../flang/Optimizer/Transforms/Passes.td | 4 +++ flang/include/flang/Tools/CrossToolHelpers.h | 3 +++ flang/lib/Frontend/CompilerInvocation.cpp | 5 ++++ flang/lib/Lower/Bridge.cpp | 15 ++++++++++- flang/lib/Optimizer/Passes/Pipelines.cpp | 4 +-- .../lib/Optimizer/Transforms/FunctionAttr.cpp | 7 +++++ .../Driver/funique-internal-linkage-names.f90 | 20 ++++++++++++++ .../unique-internal-linkage-names.f90 | 22 ++++++++++++++++ ...on-attrs-unique-internal-linkage-names.fir | 26 +++++++++++++++++++ mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 3 ++- mlir/lib/Target/LLVMIR/ModuleImport.cpp | 7 +++++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 5 ++++ .../sample-profile-suffix-elision-policy.ll | 15 +++++++++++ .../sample-profile-suffix-elision-policy.mlir | 7 +++++ 18 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 flang/test/Driver/funique-internal-linkage-names.f90 create mode 100644 flang/test/Integration/unique-internal-linkage-names.f90 create mode 100644 flang/test/Transforms/function-attrs-unique-internal-linkage-names.fir create mode 100644 mlir/test/Target/LLVMIR/Import/sample-profile-suffix-elision-policy.ll create mode 100644 mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index d4bf48040029f5..80fda1515d8cb5 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -5089,10 +5089,10 @@ defm unique_basic_block_section_names : BoolFOption<"unique-basic-block-section- NegFlag<SetFalse>>; defm unique_internal_linkage_names : BoolFOption<"unique-internal-linkage-names", CodeGenOpts<"UniqueInternalLinkageNames">, DefaultFalse, - PosFlag<SetTrue, [], [ClangOption, CC1Option], + PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Uniqueify Internal Linkage Symbol Names by appending" " the MD5 hash of the module path">, - NegFlag<SetFalse>>; + NegFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption, FC1Option]>>; defm unique_section_names : BoolFOption<"unique-section-names", CodeGenOpts<"UniqueSectionNames">, DefaultTrue, NegFlag<SetFalse, [], [ClangOption, CC1Option], diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 95a11eb36be080..70e71fe42f1199 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -357,6 +357,9 @@ void Flang::addCodegenOptions(const ArgList &Args, options::OPT_fno_experimental_loop_fusion); Args.AddLastArg(CmdArgs, options::OPT_ffp_sum_reassociation, options::OPT_fno_fp_sum_reassociation); + + Args.addOptInFlag(CmdArgs, options::OPT_funique_internal_linkage_names, + options::OPT_fno_unique_internal_linkage_names); handleInterchangeLoopsArgs(Args, CmdArgs); handleVectorizeLoopsArgs(Args, CmdArgs); diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index a036311829e280..86994f7710576c 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -61,6 +61,7 @@ CODEGENOPT(AliasAnalysis, 1, 0) ///< Enable alias analysis pass CODEGENOPT(DwarfVersion, 3, 0) ///< Dwarf version CODEGENOPT(DebugInfoForProfiling, 1, 0) ///< Emit extra debug info to make sample profile more accurate. CODEGENOPT(PseudoProbeForProfiling, 1, 0) ///< Emit pseudo probes for sample profiling. +CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Append MD5 hash to internal linkage symbols. CODEGENOPT(Underscoring, 1, 1) ENUM_CODEGENOPT(FPMaxminBehavior, Fortran::common::FPMaxminBehavior, 2, Fortran::common::FPMaxminBehavior::Legacy) diff --git a/flang/include/flang/Lower/Bridge.h b/flang/include/flang/Lower/Bridge.h index dbddef7b1169d1..f8421f27e6ec25 100644 --- a/flang/include/flang/Lower/Bridge.h +++ b/flang/include/flang/Lower/Bridge.h @@ -24,6 +24,7 @@ #include "flang/Support/Fortran.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/OwningOpRef.h" +#include "llvm/ProfileData/SampleProf.h" #include <set> namespace llvm { @@ -118,6 +119,8 @@ class LoweringBridge { return languageFeatures; } + const std::string &getModuleNameHash() const { return moduleNameHash; } + /// Create a folding context. Careful: this is very expensive. Fortran::evaluate::FoldingContext createFoldingContext(); @@ -180,6 +183,7 @@ class LoweringBridge { const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults; const Fortran::common::LanguageFeatureControl &languageFeatures; std::set<std::string> tempNames; + std::string moduleNameHash; std::optional<mlir::DiagnosticEngine::HandlerID> diagHandlerID; }; diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 619f44e53bac5f..f857e19f4ae461 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -527,6 +527,10 @@ def FunctionAttr : Pass<"function-attr", "mlir::func::FuncOp"> { /*default=*/"false", "Set the disable-tail-calls attribute on functions to prevent " "tail call optimization.">, + Option<"UniqueInternalLinkageNames", "unique-internal-linkage-names", + "bool", /*default=*/"false", + "Set the sample-profile-suffix-elision-policy attribute on " + "internal linkage functions in the module.">, Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"", "Set the tune-cpu attribute on functions in the module.">, Option<"setNoCapture", "set-nocapture", "bool", /*default=*/"false", diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 692b7fd7129f2e..b9add141663b9c 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -138,6 +138,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { Reciprocals = opts.Reciprocals; PreferVectorWidth = opts.PreferVectorWidth; UseSampleProfile = !opts.SampleProfileFile.empty(); + UniqueInternalLinkageNames = opts.UniqueInternalLinkageNames; DebugInfoForProfiling = opts.DebugInfoForProfiling; if (opts.InstrumentFunctions) { InstrumentFunctionEntry = "__cyg_profile_func_enter"; @@ -178,6 +179,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool EnableOpenMPIsTargetDevice = false; ///< Compiling for an OpenMP target device. bool UseSampleProfile = false; ///< Enable sample based profiling + bool UniqueInternalLinkageNames = false; ///< Append MD5 hash suffix to + ///< internal linkage symbol names. bool DebugInfoForProfiling = false; ///< Enable extra debugging info bool DisableTailCalls = false; ///< Disable tail call optimization bool EnableOpenMPSimd = false; ///< Enable OpenMP simd-only mode. diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 85e5f477dcb8c7..253c7932202a39 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -317,6 +317,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, clang::options::OPT_fno_safe_trampoline, false)) opts.EnableSafeTrampoline = 1; + if (args.hasFlag(clang::options::OPT_funique_internal_linkage_names, + clang::options::OPT_fno_unique_internal_linkage_names, + false)) + opts.UniqueInternalLinkageNames = 1; + if (args.hasFlag(clang::options::OPT_ffp_sum_reassociation, clang::options::OPT_fno_fp_sum_reassociation, true)) opts.SplitSumExpressionTree = 1; diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 784a87cc619979..ddf8fbecd987ce 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -1239,9 +1239,15 @@ class FirConverter : public Fortran::lower::AbstractConverter { } std::string mangleName(const Fortran::semantics::Symbol &symbol) override final { - return Fortran::lower::mangle::mangleName( + std::string mangledName = Fortran::lower::mangle::mangleName( symbol, scopeBlockIdMap, /*keepExternalInScope=*/false, getLoweringOptions().getUnderscoring()); + const auto &hash = bridge.getModuleNameHash(); + if (!hash.empty() && + Fortran::semantics::ClassifyProcedure(symbol) == + Fortran::semantics::ProcedureDefinitionClass::Internal) + mangledName += hash; + return mangledName; } std::string mangleName( const Fortran::semantics::DerivedTypeSpec &derivedType) override final { @@ -7136,6 +7142,13 @@ Fortran::lower::LoweringBridge::LoweringBridge( else if (languageFeatures.IsEnabled( Fortran::common::LanguageFeature::CudaManaged)) fir::setCudaHeapAllocMode(*module, fir::CudaHeapAllocMode::Managed); + + if (cgOpts.UniqueInternalLinkageNames) { + if (auto fileLoc = mlir::dyn_cast<mlir::FileLineColLoc>(module->getLoc())) { + moduleNameHash = + llvm::getUniqueInternalLinkagePostfix(fileLoc.getFilename()); + } + } } Fortran::lower::LoweringBridge::~LoweringBridge() { diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index b73a1ce4a47c64..517f7995ac340c 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -464,8 +464,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath, config.ApproxFuncFPMath, config.NoSignedZerosFPMath, config.UnsafeFPMath, config.Reciprocals, config.PreferVectorWidth, config.UseSampleProfile, - config.DisableTailCalls, /*tuneCPU=*/"", setNoCapture, setNoAlias, - setReadOnly})); + config.DisableTailCalls, config.UniqueInternalLinkageNames, /*tuneCPU=*/"", + setNoCapture, setNoAlias, setReadOnly})); if (config.EnableOpenMP) { pm.addNestedPass<mlir::func::FuncOp>( diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp index 1aadd16fe1cf44..958a9ea87cd6d8 100644 --- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp +++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp @@ -144,6 +144,13 @@ void FunctionAttrPass::runOnOperation() { context, mlir::LLVM::LLVMFuncOp::getUseSampleProfileAttrName( llvmFuncOpName)), mlir::BoolAttr::get(context, true)); + if (UniqueInternalLinkageNames && fir::isInternalProcedure(func)) + func->setAttr( + getLlvmFuncPropertyAttrName( + context, + mlir::LLVM::LLVMFuncOp::getSampleProfileSuffixElisionPolicyAttrName( + llvmFuncOpName)), + mlir::StringAttr::get(context, "selected")); if (disableTailCalls) func->setAttr( diff --git a/flang/test/Driver/funique-internal-linkage-names.f90 b/flang/test/Driver/funique-internal-linkage-names.f90 new file mode 100644 index 00000000000000..88cafb520a0192 --- /dev/null +++ b/flang/test/Driver/funique-internal-linkage-names.f90 @@ -0,0 +1,20 @@ +! Test that -funique-internal-linkage-names / -fno-unique-internal-linkage-names are forwarded to flang -fc1. + +! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=DEFAULT +! RUN: %flang -### -funique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=ENABLED +! RUN: %flang -### -fno-unique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=DISABLED +! RUN: %flang -### -funique-internal-linkage-names -fno-unique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=DISABLED +! RUN: %flang -### -fno-unique-internal-linkage-names -funique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=ENABLED + +! DEFAULT-NOT: "-funique-internal-linkage-names" +! DEFAULT-NOT: "-fno-unique-internal-linkage-names" + +! ENABLED: "-fc1"{{.*}}"-funique-internal-linkage-names" +! DISABLED-NOT: "-funique-internal-linkage-names" + +subroutine host() + call inner() +contains + subroutine inner() + end subroutine +end subroutine diff --git a/flang/test/Integration/unique-internal-linkage-names.f90 b/flang/test/Integration/unique-internal-linkage-names.f90 new file mode 100644 index 00000000000000..c96e854b8eae44 --- /dev/null +++ b/flang/test/Integration/unique-internal-linkage-names.f90 @@ -0,0 +1,22 @@ +! Test that -funique-internal-linkage-names appends a hash suffix to internal +! procedures and sets the "sample-profile-suffix-elision-policy" attribute. + +! RUN: %flang_fc1 -emit-llvm -funique-internal-linkage-names -o - %s | FileCheck %s + +! CHECK-LABEL: define void @test_( +! CHECK : call void @_QFtestPfooX__uniqX{{[0-9]+}}(ptr {{.*}}) + +! CHECK-LABEL: define internal void @_QFtestPfooX__uniqX{{[0-9]+}}(ptr {{.*}}) #0 +! CHECK-NOT : define internal void @_QFtestPfoo( + +! CHECK: attributes #0 = { "sample-profile-suffix-elision-policy"="selected" } + +subroutine test(x) + integer, intent(inout) :: x + call foo(x) +contains + subroutine foo(y) + integer, intent(inout) :: y + y = y + 1 + end subroutine +end subroutine diff --git a/flang/test/Transforms/function-attrs-unique-internal-linkage-names.fir b/flang/test/Transforms/function-attrs-unique-internal-linkage-names.fir new file mode 100644 index 00000000000000..9d5cf40ea6e35a --- /dev/null +++ b/flang/test/Transforms/function-attrs-unique-internal-linkage-names.fir @@ -0,0 +1,26 @@ +// RUN: fir-opt --function-attr="unique-internal-linkage-names=true" %s | FileCheck %s --check-prefix=ENABLED +// RUN: fir-opt --function-attr="unique-internal-linkage-names=false" %s | FileCheck %s --check-prefix=DISABLED + +// Internal procedure: has fir.host_symbol, should get the attribute. +// ENABLED-LABEL: func.func @_QFhost_subPinner( +// ENABLED-SAME: llvm.sample_profile_suffix_elision_policy = "selected" + +// DISABLED-LABEL: func.func @_QFhost_subPinner( +// DISABLED-NOT: sample_profile_suffix_elision_policy +func.func @_QFhost_subPinner(%arg0: !fir.ref<i32>) attributes {fir.host_symbol = @_QFhost_sub} { + return +} + +// Host procedure: no fir.host_symbol, should NOT get the attribute. +// ENABLED-LABEL: func.func @_QFhost_sub( +// ENABLED-NOT: sample_profile_suffix_elision_policy +func.func @_QFhost_sub(%arg0: !fir.ref<i32>) { + return +} + +// External procedure: should NOT get the attribute. +// ENABLED-LABEL: func.func @_QPexternal_sub( +// ENABLED-NOT: sample_profile_suffix_elision_policy +func.func @_QPexternal_sub(%arg0: !fir.ref<i32>) { + return +} diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 5998bd01f9bdf5..c8efc741d0acb6 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -2160,7 +2160,8 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [ OptionalAttr<LLVM_FunctionMetadataArrayAttr>:$function_metadata, OptionalAttr<UWTableKindAttr>:$uwtable_kind, OptionalAttr<BoolAttr>:$use_sample_profile, - OptionalAttr<BoolAttr>:$disable_tail_calls + OptionalAttr<BoolAttr>:$disable_tail_calls, + OptionalAttr<StrAttr>:$sample_profile_suffix_elision_policy ); let regions = (region AnyRegion:$body); diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index bfecde8b664a9b..ab7eb2e690d57f 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -2927,6 +2927,7 @@ static constexpr std::array kExplicitLLVMFuncOpAttributes{ StringLiteral("save-reg-params"), StringLiteral("target-features"), StringLiteral("trap-func-name"), + StringLiteral("sample-profile-suffix-elision-policy"), StringLiteral("tune-cpu"), StringLiteral("uniform-work-group-size"), StringLiteral("uwtable"), @@ -3103,6 +3104,12 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func, emitError(funcOp.getLoc()) << "unknown value '" << val << "' for 'disable-tail-calls' attribute"; } + + if (llvm::Attribute attr = + func->getFnAttribute("sample-profile-suffix-elision-policy"); + attr.isStringAttribute()) + funcOp.setSampleProfileSuffixElisionPolicy( + StringAttr::get(context, attr.getValueAsString())); if (llvm::Attribute attr = func->getFnAttribute("target-cpu"); attr.isStringAttribute()) diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 50365b5a5b3a13..0cce25c6275bc9 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1745,6 +1745,11 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) { if (auto disableTailCalls = func.getDisableTailCalls()) llvmFunc->addFnAttr("disable-tail-calls", llvm::toStringRef(*disableTailCalls)); + + if (auto sampleProfileSuffixElisionPolicy = + func.getSampleProfileSuffixElisionPolicy()) + llvmFunc->addFnAttr("sample-profile-suffix-elision-policy", + *sampleProfileSuffixElisionPolicy); if (auto attr = func.getVscaleRange()) llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs( diff --git a/mlir/test/Target/LLVMIR/Import/sample-profile-suffix-elision-policy.ll b/mlir/test/Target/LLVMIR/Import/sample-profile-suffix-elision-policy.ll new file mode 100644 index 00000000000000..8f9a59fea827cf --- /dev/null +++ b/mlir/test/Target/LLVMIR/Import/sample-profile-suffix-elision-policy.ll @@ -0,0 +1,15 @@ +; RUN: mlir-translate -import-llvm %s | FileCheck %s + +; CHECK-LABEL: llvm.func @with_elision_policy() +; CHECK-SAME: sample_profile_suffix_elision_policy = "selected" +define void @with_elision_policy() #0 { + ret void +} + +; CHECK-LABEL: llvm.func @without_elision_policy() +; CHECK-NOT: sample_profile_suffix_elision_policy +define void @without_elision_policy() { + ret void +} + +attributes #0 = { "sample-profile-suffix-elision-policy"="selected" } diff --git a/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir b/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir new file mode 100644 index 00000000000000..4882a886d45588 --- /dev/null +++ b/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir @@ -0,0 +1,7 @@ +// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s + +// CHECK: define void @with_elision_policy() #[[ATTRS:.*]] { +// CHECK: attributes #[[ATTRS]] = { "sample-profile-suffix-elision-policy"="selected" } +llvm.func @with_elision_policy() attributes {sample_profile_suffix_elision_policy = "selected"} { + llvm.return +} >From 100409b530d484716adc71a5fca2c17f15436c13 Mon Sep 17 00:00:00 2001 From: Kaviya Rajendiran <[email protected]> Date: Thu, 20 Aug 2026 00:56:31 +0530 Subject: [PATCH 2/3] [Flang] Preserve .__uniq. suffix in CompilerGeneratedNamesConversion pass and added new testcases --- clang/include/clang/Options/Options.td | 2 +- clang/lib/Driver/ToolChains/Flang.cpp | 4 +-- flang/lib/Frontend/CompilerInvocation.cpp | 8 +++--- .../Transforms/CompilerGeneratedNames.cpp | 2 ++ .../Driver/funique-internal-linkage-names.f90 | 17 +++++------- .../unique-internal-linkage-names.f90 | 22 ---------------- .../Lower/unique-internal-linkage-names.f90 | 20 ++++++++++++++ ...ion-attr-unique-internal-linkage-names.fir | 26 +++++++++++++++++++ .../LLVMIR/unique-internal-linkage-names.mlir | 20 ++++++++++++++ 9 files changed, 80 insertions(+), 41 deletions(-) delete mode 100644 flang/test/Integration/unique-internal-linkage-names.f90 create mode 100644 flang/test/Lower/unique-internal-linkage-names.f90 create mode 100644 flang/test/Transforms/function-attr-unique-internal-linkage-names.fir create mode 100644 mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 80fda1515d8cb5..15b2196b68e76e 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -5092,7 +5092,7 @@ defm unique_internal_linkage_names : BoolFOption<"unique-internal-linkage-names" PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Uniqueify Internal Linkage Symbol Names by appending" " the MD5 hash of the module path">, - NegFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption, FC1Option]>>; + NegFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption]>>; defm unique_section_names : BoolFOption<"unique-section-names", CodeGenOpts<"UniqueSectionNames">, DefaultTrue, NegFlag<SetFalse, [], [ClangOption, CC1Option], diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 70e71fe42f1199..b333f0d56a3958 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -357,9 +357,9 @@ void Flang::addCodegenOptions(const ArgList &Args, options::OPT_fno_experimental_loop_fusion); Args.AddLastArg(CmdArgs, options::OPT_ffp_sum_reassociation, options::OPT_fno_fp_sum_reassociation); - + Args.addOptInFlag(CmdArgs, options::OPT_funique_internal_linkage_names, - options::OPT_fno_unique_internal_linkage_names); + options::OPT_fno_unique_internal_linkage_names); handleInterchangeLoopsArgs(Args, CmdArgs); handleVectorizeLoopsArgs(Args, CmdArgs); diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 253c7932202a39..1dd28e4f0a99b5 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -317,11 +317,6 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, clang::options::OPT_fno_safe_trampoline, false)) opts.EnableSafeTrampoline = 1; - if (args.hasFlag(clang::options::OPT_funique_internal_linkage_names, - clang::options::OPT_fno_unique_internal_linkage_names, - false)) - opts.UniqueInternalLinkageNames = 1; - if (args.hasFlag(clang::options::OPT_ffp_sum_reassociation, clang::options::OPT_fno_fp_sum_reassociation, true)) opts.SplitSumExpressionTree = 1; @@ -332,6 +327,9 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, args.hasFlag(clang::options::OPT_floop_interchange, clang::options::OPT_fno_loop_interchange, true); + if (args.hasArg(clang::options::OPT_funique_internal_linkage_names)) + opts.UniqueInternalLinkageNames = 1; + if (args.getLastArg(clang::options::OPT_fexperimental_loop_fusion)) opts.FuseLoops = 1; diff --git a/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp b/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp index 7a173da514b168..ca33639bbb8885 100644 --- a/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp +++ b/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp @@ -45,6 +45,8 @@ void CompilerGeneratedNamesConversionPass::runOnOperation() { auto processOp = [&](mlir::Operation &op) { auto symName = mlir::cast<mlir::SymbolOpInterface>(&op).getNameAttr(); + if (symName.getValue().contains(".__uniq.")) + return; auto deconstructedName = fir::NameUniquer::deconstruct(symName); if (deconstructedName.first != fir::NameUniquer::NameKind::NOT_UNIQUED && !fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) { diff --git a/flang/test/Driver/funique-internal-linkage-names.f90 b/flang/test/Driver/funique-internal-linkage-names.f90 index 88cafb520a0192..6192e3617cec04 100644 --- a/flang/test/Driver/funique-internal-linkage-names.f90 +++ b/flang/test/Driver/funique-internal-linkage-names.f90 @@ -1,20 +1,15 @@ ! Test that -funique-internal-linkage-names / -fno-unique-internal-linkage-names are forwarded to flang -fc1. -! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=DEFAULT +! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=DISABLED ! RUN: %flang -### -funique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=ENABLED ! RUN: %flang -### -fno-unique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=DISABLED ! RUN: %flang -### -funique-internal-linkage-names -fno-unique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=DISABLED ! RUN: %flang -### -fno-unique-internal-linkage-names -funique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=ENABLED -! DEFAULT-NOT: "-funique-internal-linkage-names" -! DEFAULT-NOT: "-fno-unique-internal-linkage-names" - -! ENABLED: "-fc1"{{.*}}"-funique-internal-linkage-names" +! DISABLED: "-fc1" ! DISABLED-NOT: "-funique-internal-linkage-names" +! DISABLED-NOT: "-fno-unique-internal-linkage-names" + +! ENABLED: "-fc1" +! ENABLED-SAME: "-funique-internal-linkage-names" -subroutine host() - call inner() -contains - subroutine inner() - end subroutine -end subroutine diff --git a/flang/test/Integration/unique-internal-linkage-names.f90 b/flang/test/Integration/unique-internal-linkage-names.f90 deleted file mode 100644 index c96e854b8eae44..00000000000000 --- a/flang/test/Integration/unique-internal-linkage-names.f90 +++ /dev/null @@ -1,22 +0,0 @@ -! Test that -funique-internal-linkage-names appends a hash suffix to internal -! procedures and sets the "sample-profile-suffix-elision-policy" attribute. - -! RUN: %flang_fc1 -emit-llvm -funique-internal-linkage-names -o - %s | FileCheck %s - -! CHECK-LABEL: define void @test_( -! CHECK : call void @_QFtestPfooX__uniqX{{[0-9]+}}(ptr {{.*}}) - -! CHECK-LABEL: define internal void @_QFtestPfooX__uniqX{{[0-9]+}}(ptr {{.*}}) #0 -! CHECK-NOT : define internal void @_QFtestPfoo( - -! CHECK: attributes #0 = { "sample-profile-suffix-elision-policy"="selected" } - -subroutine test(x) - integer, intent(inout) :: x - call foo(x) -contains - subroutine foo(y) - integer, intent(inout) :: y - y = y + 1 - end subroutine -end subroutine diff --git a/flang/test/Lower/unique-internal-linkage-names.f90 b/flang/test/Lower/unique-internal-linkage-names.f90 new file mode 100644 index 00000000000000..811519f3db5abd --- /dev/null +++ b/flang/test/Lower/unique-internal-linkage-names.f90 @@ -0,0 +1,20 @@ +! Test that -funique-internal-linkage-names appends a .__uniq. hash suffix +! to internal procedures at the FIR level. + +! RUN: %flang_fc1 -emit-fir -funique-internal-linkage-names -o - %s | FileCheck %s + +! CHECK-LABEL: func.func @_QPtest +! CHECK: fir.call @_QFtestPfoo.__uniq.{{[0-9]+}} + +! CHECK: func.func private @_QFtestPfoo.__uniq.{{[0-9]+}} +! CHECK-SAME: attributes {fir.host_symbol = @_QPtest, llvm.linkage = #llvm.linkage<internal>} + +subroutine test(x) + integer, intent(inout) :: x + call foo(x) +contains + subroutine foo(y) + integer, intent(inout) :: y + y = y + 1 + end subroutine +end subroutine diff --git a/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir b/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir new file mode 100644 index 00000000000000..0284f75004b628 --- /dev/null +++ b/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir @@ -0,0 +1,26 @@ +// RUN: fir-opt --function-attr="unique-internal-linkage-names=true" %s | FileCheck %s --check-prefix=ENABLED +// RUN: fir-opt --function-attr="unique-internal-linkage-names=false" %s | FileCheck %s --check-prefix=DISABLED + +// ENABLED: func.func @_QPtest() { +// ENABLED-NEXT: return +// ENABLED-NEXT: } + +// DISABLED: func.func @_QPtest() { +// DISABLED-NEXT: return +// DISABLED-NEXT: } +func.func @_QPtest() { + return +} + +// ENABLED: func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest, llvm.sample_profile_suffix_elision_policy = "selected"} { +// ENABLED-NEXT: return +// ENABLED-NEXT: } + +// DISABLED: func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest} { +// DISABLED-NEXT: return +// DISABLED-NEXT: } + +func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest} { + return +} + diff --git a/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir b/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir new file mode 100644 index 00000000000000..a1113caed3ed11 --- /dev/null +++ b/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir @@ -0,0 +1,20 @@ +// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s + +// CHECK-LABEL: define void @test_(ptr noalias %0) +// CHECK: call void @_QFtestPfoo.__uniq.12345(ptr %0) + +llvm.func @test_(%arg0: !llvm.ptr {llvm.noalias}) { + llvm.call @_QFtestPfoo.__uniq.12345(%arg0) : (!llvm.ptr) -> () + llvm.return +} + +// CHECK-LABEL: define internal void @_QFtestPfoo.__uniq.12345(ptr noalias %0) +llvm.func internal @_QFtestPfoo.__uniq.12345(%arg0: !llvm.ptr {llvm.noalias}) attributes {sample_profile_suffix_elision_policy = "selected"} { + %0 = llvm.load %arg0 : !llvm.ptr -> i32 + %1 = llvm.mlir.constant(1 : i32) : i32 + %2 = llvm.add %0, %1 : i32 + llvm.store %2, %arg0 : i32, !llvm.ptr + llvm.return +} + +// CHECK: attributes #[[ATTRS:.*]] = { "sample-profile-suffix-elision-policy"="selected" } >From 882e73beaf693b5973d8c01451978683628dc4f1 Mon Sep 17 00:00:00 2001 From: Kaviya Rajendiran <[email protected]> Date: Fri, 28 Aug 2026 15:58:33 +0530 Subject: [PATCH 3/3] [Flang] Addressed review comment and modified testcases and formatting issues --- flang/lib/Lower/Bridge.cpp | 2 +- flang/lib/Optimizer/Passes/Pipelines.cpp | 4 +-- .../Driver/funique-internal-linkage-names.f90 | 1 - .../Lower/unique-internal-linkage-names.f90 | 9 +++---- ...ion-attr-unique-internal-linkage-names.fir | 26 ------------------- mlir/lib/Target/LLVMIR/ModuleImport.cpp | 2 +- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 2 +- .../sample-profile-suffix-elision-policy.mlir | 11 ++++++-- .../LLVMIR/unique-internal-linkage-names.mlir | 20 -------------- 9 files changed, 17 insertions(+), 60 deletions(-) delete mode 100644 flang/test/Transforms/function-attr-unique-internal-linkage-names.fir delete mode 100644 mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index ddf8fbecd987ce..968cdbc951ecc4 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -1242,7 +1242,7 @@ class FirConverter : public Fortran::lower::AbstractConverter { std::string mangledName = Fortran::lower::mangle::mangleName( symbol, scopeBlockIdMap, /*keepExternalInScope=*/false, getLoweringOptions().getUnderscoring()); - const auto &hash = bridge.getModuleNameHash(); + const std::string &hash = bridge.getModuleNameHash(); if (!hash.empty() && Fortran::semantics::ClassifyProcedure(symbol) == Fortran::semantics::ProcedureDefinitionClass::Internal) diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index 517f7995ac340c..fc5b5ef6460a92 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -464,8 +464,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath, config.ApproxFuncFPMath, config.NoSignedZerosFPMath, config.UnsafeFPMath, config.Reciprocals, config.PreferVectorWidth, config.UseSampleProfile, - config.DisableTailCalls, config.UniqueInternalLinkageNames, /*tuneCPU=*/"", - setNoCapture, setNoAlias, setReadOnly})); + config.DisableTailCalls, config.UniqueInternalLinkageNames, + /*tuneCPU=*/"", setNoCapture, setNoAlias, setReadOnly})); if (config.EnableOpenMP) { pm.addNestedPass<mlir::func::FuncOp>( diff --git a/flang/test/Driver/funique-internal-linkage-names.f90 b/flang/test/Driver/funique-internal-linkage-names.f90 index 6192e3617cec04..d81e405cff5411 100644 --- a/flang/test/Driver/funique-internal-linkage-names.f90 +++ b/flang/test/Driver/funique-internal-linkage-names.f90 @@ -12,4 +12,3 @@ ! ENABLED: "-fc1" ! ENABLED-SAME: "-funique-internal-linkage-names" - diff --git a/flang/test/Lower/unique-internal-linkage-names.f90 b/flang/test/Lower/unique-internal-linkage-names.f90 index 811519f3db5abd..7699212ddff3a7 100644 --- a/flang/test/Lower/unique-internal-linkage-names.f90 +++ b/flang/test/Lower/unique-internal-linkage-names.f90 @@ -9,12 +9,9 @@ ! CHECK: func.func private @_QFtestPfoo.__uniq.{{[0-9]+}} ! CHECK-SAME: attributes {fir.host_symbol = @_QPtest, llvm.linkage = #llvm.linkage<internal>} -subroutine test(x) - integer, intent(inout) :: x - call foo(x) +subroutine test() + call foo() contains - subroutine foo(y) - integer, intent(inout) :: y - y = y + 1 + subroutine foo() end subroutine end subroutine diff --git a/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir b/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir deleted file mode 100644 index 0284f75004b628..00000000000000 --- a/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: fir-opt --function-attr="unique-internal-linkage-names=true" %s | FileCheck %s --check-prefix=ENABLED -// RUN: fir-opt --function-attr="unique-internal-linkage-names=false" %s | FileCheck %s --check-prefix=DISABLED - -// ENABLED: func.func @_QPtest() { -// ENABLED-NEXT: return -// ENABLED-NEXT: } - -// DISABLED: func.func @_QPtest() { -// DISABLED-NEXT: return -// DISABLED-NEXT: } -func.func @_QPtest() { - return -} - -// ENABLED: func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest, llvm.sample_profile_suffix_elision_policy = "selected"} { -// ENABLED-NEXT: return -// ENABLED-NEXT: } - -// DISABLED: func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest} { -// DISABLED-NEXT: return -// DISABLED-NEXT: } - -func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest} { - return -} - diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index ab7eb2e690d57f..04f69433b97a00 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -3104,7 +3104,7 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func, emitError(funcOp.getLoc()) << "unknown value '" << val << "' for 'disable-tail-calls' attribute"; } - + if (llvm::Attribute attr = func->getFnAttribute("sample-profile-suffix-elision-policy"); attr.isStringAttribute()) diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 0cce25c6275bc9..bd11a493f4bd3d 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1745,7 +1745,7 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) { if (auto disableTailCalls = func.getDisableTailCalls()) llvmFunc->addFnAttr("disable-tail-calls", llvm::toStringRef(*disableTailCalls)); - + if (auto sampleProfileSuffixElisionPolicy = func.getSampleProfileSuffixElisionPolicy()) llvmFunc->addFnAttr("sample-profile-suffix-elision-policy", diff --git a/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir b/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir index 4882a886d45588..49536205713186 100644 --- a/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir +++ b/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir @@ -1,7 +1,14 @@ // RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s -// CHECK: define void @with_elision_policy() #[[ATTRS:.*]] { -// CHECK: attributes #[[ATTRS]] = { "sample-profile-suffix-elision-policy"="selected" } +// CHECK: define void @with_elision_policy() #[[ATTRS_WITH:.*]] { llvm.func @with_elision_policy() attributes {sample_profile_suffix_elision_policy = "selected"} { llvm.return } + +// CHECK: define void @without_elision_policy() { +// CHECK-NOT: "sample-profile-suffix-elision-policy" +llvm.func @without_elision_policy() { + llvm.return +} + +// CHECK: attributes #[[ATTRS_WITH]] = { "sample-profile-suffix-elision-policy"="selected" } diff --git a/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir b/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir deleted file mode 100644 index a1113caed3ed11..00000000000000 --- a/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s - -// CHECK-LABEL: define void @test_(ptr noalias %0) -// CHECK: call void @_QFtestPfoo.__uniq.12345(ptr %0) - -llvm.func @test_(%arg0: !llvm.ptr {llvm.noalias}) { - llvm.call @_QFtestPfoo.__uniq.12345(%arg0) : (!llvm.ptr) -> () - llvm.return -} - -// CHECK-LABEL: define internal void @_QFtestPfoo.__uniq.12345(ptr noalias %0) -llvm.func internal @_QFtestPfoo.__uniq.12345(%arg0: !llvm.ptr {llvm.noalias}) attributes {sample_profile_suffix_elision_policy = "selected"} { - %0 = llvm.load %arg0 : !llvm.ptr -> i32 - %1 = llvm.mlir.constant(1 : i32) : i32 - %2 = llvm.add %0, %1 : i32 - llvm.store %2, %arg0 : i32, !llvm.ptr - llvm.return -} - -// CHECK: attributes #[[ATTRS:.*]] = { "sample-profile-suffix-elision-policy"="selected" } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
