1111// `unsigned long`, and `char` to appear as if they use `long long`,
1212// `unsigned long long`, and `signed char`, as is consistent with the primitive
1313// types defined by OpenCL C. Following a remangling, the original function
14- // mangling will be made an alias to either the remangled function or a function
15- // with a suitable function if any exists. In some cases an alias of the
16- // remangled function is created for functions where multiple parameters have
17- // been replaced, and the replaced values are aliases.
14+ // mangling will be built as a clone of either the remangled function or a
15+ // function with a suitable function if any exists. In some cases a clone of
16+ // the remangled function is created for functions where multiple parameters
17+ // have been replaced, and the replaced values are aliases.
1818//
19- // Original Alias Example:
19+ // Original Clone Example:
2020// If libclc defined a function `f(long)` the mangled name would be
2121// `_Z1fl`. The remangler would rename this function to `_Z1fx`
22- // (`f(long long)`.) If the target uses 64-bit `long`, `_Z1fl` is made
23- // an alias to the old function now under the name `_Z1fx`, whereas if
24- // the target uses 32-bit `long`, `_Z1fl` is made an alias to `_Z1fi`
22+ // (`f(long long)`.) If the target uses 64-bit `long`, `_Z1fl` is
23+ // cloned from the old function now under the name `_Z1fx`, whereas if
24+ // the target uses 32-bit `long`, `_Z1fl` is cloned from `_Z1fi`
2525// (`f(int)`) if such a function exists.
2626//
27- // Remangled Alias Example:
27+ // Remangled Clone Example:
2828// In cases where the remangled name squashes valid versions of a
29- // function an alias is created. `f(long, char, signed char)` would be
29+ // function a clone is created. `f(long, char, signed char)` would be
3030// mangled to
3131// `_Z1flca`. The remangler would rename this function to `_Z1fyaa`
3232// (`f(long long, signed char, signed char)`). If the target uses a
33- // signed char then a valid alias `_Z1fyca`,
33+ // signed char then a valid clone `_Z1fyca`,
3434// (`f(long long, char, signed char)`), is not defined. The remangler
35- // creates an alias of the renamed function,`_Z1fyaa` , to this
35+ // creates a clone of the renamed function,`_Z1fyaa` , to this
3636// permutation, `_Z1fyca`.
3737//
3838// ===----------------------------------------------------------------------===//
5858#include " llvm/Support/Signals.h"
5959#include " llvm/Support/ToolOutputFile.h"
6060#include " llvm/Support/raw_ostream.h"
61+ #include " llvm/Transforms/Utils/Cloning.h"
62+ #include " llvm/Transforms/Utils/ValueMapper.h"
6163
6264#include < iostream>
6365#include < memory>
@@ -153,7 +155,7 @@ class DefaultAllocator {
153155public:
154156 void reset () { Alloc.reset (); }
155157
156- template <typename T, typename ... Args> T *makeNode (Args &&... args) {
158+ template <typename T, typename ... Args> T *makeNode (Args &&...args) {
157159 return new (Alloc.allocate (sizeof (T))) T (std::forward<Args>(args)...);
158160 }
159161
@@ -478,19 +480,19 @@ class Remangler {
478480
479481class TargetTypeReplacements {
480482 SmallDenseMap<const char *, const char *> ParameterTypeReplacements;
481- SmallDenseMap<const char *, const char *> AliasTypeReplacements ;
482- SmallDenseMap<const char *, const char *> RemangledAliasTypeReplacements ;
483+ SmallDenseMap<const char *, const char *> CloneTypeReplacements ;
484+ SmallDenseMap<const char *, const char *> RemangledCloneTypeReplacements ;
483485
484486 void CreateRemangledTypeReplacements () {
485487 // RemangleTypes which are not aliases or not the exact same alias type
486488 for (auto &TypeReplacementPair : ParameterTypeReplacements)
487- if (AliasTypeReplacements .find (TypeReplacementPair.getFirst ()) ==
488- AliasTypeReplacements .end ())
489- RemangledAliasTypeReplacements [TypeReplacementPair.getFirst ()] =
489+ if (CloneTypeReplacements .find (TypeReplacementPair.getFirst ()) ==
490+ CloneTypeReplacements .end ())
491+ RemangledCloneTypeReplacements [TypeReplacementPair.getFirst ()] =
490492 TypeReplacementPair.getSecond ();
491- else if (AliasTypeReplacements [TypeReplacementPair.getFirst ()] !=
493+ else if (CloneTypeReplacements [TypeReplacementPair.getFirst ()] !=
492494 TypeReplacementPair.getSecond ())
493- RemangledAliasTypeReplacements [TypeReplacementPair.getFirst ()] =
495+ RemangledCloneTypeReplacements [TypeReplacementPair.getFirst ()] =
494496 TypeReplacementPair.getSecond ();
495497 }
496498
@@ -503,22 +505,22 @@ class TargetTypeReplacements {
503505 // Replace char with signed char
504506 ParameterTypeReplacements[" char" ] = " signed char" ;
505507
506- // Make replaced long functions aliases to either integer or long long
508+ // Make replaced long functions clones of either integer or long long
507509 // variant
508510 if (LongWidth == SupportedLongWidth::L32) {
509- AliasTypeReplacements [" long" ] = " int" ;
510- AliasTypeReplacements [" unsigned long" ] = " unsigned int" ;
511+ CloneTypeReplacements [" long" ] = " int" ;
512+ CloneTypeReplacements [" unsigned long" ] = " unsigned int" ;
511513 } else {
512- AliasTypeReplacements [" long" ] = " long long" ;
513- AliasTypeReplacements [" unsigned long" ] = " unsigned long long" ;
514+ CloneTypeReplacements [" long" ] = " long long" ;
515+ CloneTypeReplacements [" unsigned long" ] = " unsigned long long" ;
514516 }
515517
516- // Make replaced char functions aliases to either integer or long long
518+ // Make replaced char functions clones of either integer or long long
517519 // variant
518520 if (CharSignedness == Signedness::Signed) {
519- AliasTypeReplacements [" char" ] = " signed char" ;
521+ CloneTypeReplacements [" char" ] = " signed char" ;
520522 } else {
521- AliasTypeReplacements [" char" ] = " unsigned char" ;
523+ CloneTypeReplacements [" char" ] = " unsigned char" ;
522524 }
523525
524526 CreateRemangledTypeReplacements ();
@@ -528,21 +530,21 @@ class TargetTypeReplacements {
528530 return ParameterTypeReplacements;
529531 }
530532
531- SmallDenseMap<const char *, const char *> getAliasTypeReplacements () {
532- return AliasTypeReplacements ;
533+ SmallDenseMap<const char *, const char *> getCloneTypeReplacements () {
534+ return CloneTypeReplacements ;
533535 }
534536
535537 SmallDenseMap<const char *, const char *>
536- getRemangledAliasTypeReplacements () {
537- return RemangledAliasTypeReplacements ;
538+ getRemangledCloneTypeReplacements () {
539+ return RemangledCloneTypeReplacements ;
538540 }
539541};
540542
541- bool createAliasFromMap (
543+ bool createCloneFromMap (
542544 Module *M, std::string originalName,
543545 const itanium_demangle::Node *functionTree,
544546 SmallDenseMap<const char *, const char *> TypeReplacements,
545- bool AliaseeTypeReplacement = false ) {
547+ bool CloneeTypeReplacement = false ) {
546548 Remangler ATR{functionTree, TypeReplacements};
547549 std::string RemangledName = ATR.remangle ();
548550
@@ -553,39 +555,41 @@ bool createAliasFromMap(
553555 if (RemangledName == originalName)
554556 return true ;
555557
556- StringRef AliasName, AliaseeName ;
557- if (AliaseeTypeReplacement ) {
558- AliasName = originalName;
559- AliaseeName = RemangledName;
558+ StringRef CloneName, CloneeName ;
559+ if (CloneeTypeReplacement ) {
560+ CloneName = originalName;
561+ CloneeName = RemangledName;
560562 } else {
561- AliasName = RemangledName;
562- AliaseeName = originalName;
563+ CloneName = RemangledName;
564+ CloneeName = originalName;
563565 }
564566
565- Function *Aliasee = M->getFunction (AliaseeName);
566- if (Aliasee) {
567- GlobalAlias::create (AliasName, Aliasee);
567+ Function *Clonee = M->getFunction (CloneeName);
568+ if (Clonee) {
569+ ValueToValueMapTy Dummy;
570+ Function *NewF = CloneFunction (Clonee, Dummy);
571+ NewF->setName (std::string (CloneName));
568572 } else if (Verbose) {
569- std::cout << " Could not create alias " << AliasName .data () << " : missing "
570- << AliaseeName .data () << std::endl;
573+ std::cout << " Could not create copy " << CloneName .data () << " : missing "
574+ << CloneeName .data () << std::endl;
571575 }
572576
573577 return true ;
574578}
575579
576- bool createAliases (Module *M, std::string originalMangledName,
577- std::string remangledName,
578- const itanium_demangle::Node *functionTree,
579- TargetTypeReplacements replacements) {
580- // create alias of original function
581- if (!createAliasFromMap (M, originalMangledName, functionTree,
582- replacements.getAliasTypeReplacements (),
583- /* AliaseeTypeReplacement = */ true ))
580+ bool createClones (Module *M, std::string originalMangledName,
581+ std::string remangledName,
582+ const itanium_demangle::Node *functionTree,
583+ TargetTypeReplacements replacements) {
584+ // create clone of original function
585+ if (!createCloneFromMap (M, originalMangledName, functionTree,
586+ replacements.getCloneTypeReplacements (),
587+ /* CloneeTypeReplacement = */ true ))
584588 return false ;
585589
586- // create alias from remangled function
587- if (!createAliasFromMap (M, remangledName, functionTree,
588- replacements.getRemangledAliasTypeReplacements ()))
590+ // create clone of remangled function
591+ if (!createCloneFromMap (M, remangledName, functionTree,
592+ replacements.getRemangledCloneTypeReplacements ()))
589593 return false ;
590594
591595 return true ;
@@ -621,10 +625,10 @@ bool remangleFunction(Function &func, Module *M,
621625 }
622626 func.setName (RemangledName);
623627
624- // Make an alias to a suitable function using the old name if there is a
625- // type-mapping and the corresponding aliasee function exists.
626- if (!createAliases (M, MangledName, RemangledName, FunctionTree,
627- replacements))
628+ // Make a clone of a suitable function using the old name if there is a
629+ // type-mapping and the corresponding clonee function exists.
630+ if (!createClones (M, MangledName, RemangledName, FunctionTree,
631+ replacements))
628632 return false ;
629633 }
630634
@@ -661,10 +665,14 @@ int main(int argc, const char **argv) {
661665 return 1 ;
662666 }
663667
664- bool Success = true ;
668+ std::vector<Function *> FuncList ;
665669 for (auto &Func : M->getFunctionList ())
666- Success = remangleFunction (Func, M. get (), Replacements) && Success ;
670+ FuncList. push_back (&Func) ;
667671
672+ bool Success = true ;
673+ for (auto Func : FuncList) {
674+ Success = remangleFunction (*Func, M.get (), Replacements) && Success;
675+ }
668676 // Only fail after all to give as much context as possible.
669677 if (!Success) {
670678 errs () << " Failed to remangle all mangled functions in module.\n " ;
0 commit comments