@@ -857,7 +857,8 @@ class LibCLCRemangler : public ASTConsumer {
857857 if (RemangledName == OriginalName)
858858 return true ;
859859
860- StringRef CloneName, CloneeName;
860+ std::string CloneName;
861+ StringRef CloneeName;
861862 if (CloneeTypeReplacement) {
862863 CloneName = OriginalName;
863864 CloneeName = RemangledName;
@@ -866,19 +867,26 @@ class LibCLCRemangler : public ASTConsumer {
866867 CloneeName = OriginalName;
867868 }
868869
869- // If the clone name already exists in the module then we have to assume it
870- // does the right thing already. We're only going to end up creating a copy
871- // of that function without external users being able to reach it.
870+ // If the clone name is an original function in the module, it may later be
871+ // remangled and must be replaced. Example (TargetDefaultAddrSpace != 0):
872+ // _Z1fPm -> remangled to _Z1fPU3AS0y; remangler clones back to _Z1fPm to
873+ // preserve the original. Later, _Z1fPU3AS4m -> remangled to _Z1fPy; we need
874+ // to clone _Z1fPy to _Z1fPm, but it already exists. To avoid a clash,
875+ // append a temporary suffix (e.g., _Z1fPm$TmpSuffix). The suffix is removed
876+ // in post-processing, and the old Z1fPm (clone of _Z1fPU3AS0y) is replaced
877+ // by Z1fPm$TmpSuffix.
872878 if (M->getFunction (CloneName)) {
873- return true ;
879+ CloneName += TmpSuffix;
880+ if (M->getFunction (CloneName))
881+ return true ;
874882 }
875883
876884 if (Function *Clonee = M->getFunction (CloneeName)) {
877885 ValueToValueMapTy Dummy;
878886 Function *NewF = CloneFunction (Clonee, Dummy);
879- NewF->setName (CloneName. str () );
887+ NewF->setName (CloneName);
880888 } else if (Verbose) {
881- errs () << " Could not create copy " << CloneName. data () << " : missing "
889+ errs () << " Could not create copy " << CloneName << " : missing "
882890 << CloneeName.data () << ' \n ' ;
883891 }
884892 return true ;
@@ -910,6 +918,7 @@ class LibCLCRemangler : public ASTConsumer {
910918 return false ;
911919
912920 if (RemangledName != MangledName) {
921+ RenamedFunctions.insert (MangledName);
913922 if (Verbose || TestRun) {
914923 errs () << " Mangling changed:"
915924 << " \n "
@@ -927,13 +936,12 @@ class LibCLCRemangler : public ASTConsumer {
927936 // RemangledName may already exist. For instance, the function name
928937 // _Z1fPU3AS4i would be remangled to _Z1fPi, which is a valid variant and
929938 // might already be present. Since we cannot alter the name of an existing
930- // variant function that may not have been processed yet, we append a
931- // temporary suffix to RemangledName to prevent a name clash. This
932- // temporary suffix will be removed during the post-processing stage, once
933- // all functions have been handled.
934- if (ASTCtx->getTargetAddressSpace (LangAS::Default) != 0 )
935- if (M->getFunction (RemangledName))
936- RemangledName += TmpSuffix;
939+ // variant function that may not have been processed yet (it will become a
940+ // clone of the original function), we append a temporary suffix to
941+ // RemangledName to prevent a name clash. This temporary suffix will be
942+ // removed eventually and Old _Z1fPi will be replaced by _Z1fPi$TmpSuffix.
943+ if (M->getFunction (RemangledName))
944+ RemangledName += TmpSuffix;
937945
938946 // If the remangled name already exists in the module then we have to
939947 // assume it does the right thing already. We're only going to end up
@@ -954,28 +962,27 @@ class LibCLCRemangler : public ASTConsumer {
954962 return true ;
955963 }
956964
957- // When TargetDefaultAddrSpace is not 0, post-processing is necessary after
958- // all functions have been processed. During this stage, the temporary suffix
959- // is removed from the remangled name.
965+ // The temporary suffix is removed from the remangled or cloned name.
960966 void postProcessRemoveTmpSuffix (llvm::Module *M) {
961967 if (TestRun)
962968 return ;
963- for (auto &F : *M ) {
969+ for (auto &F : make_early_inc_range (*M) ) {
964970 StringRef Name = F.getName ();
965971 if (!Name.consume_back (TmpSuffix))
966972 continue ;
967- // If a name clash persists, the old function is renamed. For example,
968- // _Z1fPi is remangled to _Z1fPU3AS0i, and the remangler clones
969- // _Z1fPU3AS0i to _Z1fPi to preserve the original implementation.
970- // Subsequently, _Z1fPU3AS4i is remangled to _Z1fPi, and the remangled
971- // name is temporarily changed to _Z1fPi$TmpSuffix. When attempting to
972- // revert _Z1fPi$TmpSuffix back to _Z1fPi, a clash occurs because _Z1fPi
973- // still exists. Delete the old _Z1fPi which is no longer useful.
974973 if (auto *Func = M->getFunction (Name)) {
975- Func->replaceAllUsesWith (ConstantPointerNull::get (Func->getType ()));
976- Func->eraseFromParent ();
974+ if (RenamedFunctions.count (Name.str ())) {
975+ // Drop unuseful clone of the original or remangled function.
976+ Func->replaceAllUsesWith (ConstantPointerNull::get (Func->getType ()));
977+ Func->eraseFromParent ();
978+ } else {
979+ // Name doesn't exist in the original module. Drop unuseful clone of
980+ // remangled function.
981+ F.eraseFromParent ();
982+ continue ;
983+ }
977984 }
978- // Complete the mangling process from _Z1fPU3AS4i to _Z1fPi.
985+ // Complete the mangling process, e.g. from _Z1fPU3AS4i to _Z1fPi.
979986 F.setName (Name);
980987 }
981988 }
@@ -1032,6 +1039,8 @@ class LibCLCRemangler : public ASTConsumer {
10321039 ASTContext *ASTCtx;
10331040 LLVMContext LLVMCtx;
10341041 TargetTypeReplacements Replacements;
1042+ // Functions in the input module that have been renamed due to remangling.
1043+ std::unordered_set<std::string> RenamedFunctions;
10351044};
10361045
10371046class LibCLCRemanglerActionFactory {
0 commit comments