11
11
// `unsigned long`, and `char` to appear as if they use `long long`,
12
12
// `unsigned long long`, and `signed char`, as is consistent with the primitive
13
13
// 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.
18
18
//
19
- // Original Alias Example:
19
+ // Original Clone Example:
20
20
// If libclc defined a function `f(long)` the mangled name would be
21
21
// `_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`
25
25
// (`f(int)`) if such a function exists.
26
26
//
27
- // Remangled Alias Example:
27
+ // Remangled Clone Example:
28
28
// 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
30
30
// mangled to
31
31
// `_Z1flca`. The remangler would rename this function to `_Z1fyaa`
32
32
// (`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`,
34
34
// (`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
36
36
// permutation, `_Z1fyca`.
37
37
//
38
38
// ===----------------------------------------------------------------------===//
58
58
#include " llvm/Support/Signals.h"
59
59
#include " llvm/Support/ToolOutputFile.h"
60
60
#include " llvm/Support/raw_ostream.h"
61
+ #include " llvm/Transforms/Utils/Cloning.h"
62
+ #include " llvm/Transforms/Utils/ValueMapper.h"
61
63
62
64
#include < iostream>
63
65
#include < memory>
@@ -153,7 +155,7 @@ class DefaultAllocator {
153
155
public:
154
156
void reset () { Alloc.reset (); }
155
157
156
- template <typename T, typename ... Args> T *makeNode (Args &&... args) {
158
+ template <typename T, typename ... Args> T *makeNode (Args &&...args) {
157
159
return new (Alloc.allocate (sizeof (T))) T (std::forward<Args>(args)...);
158
160
}
159
161
@@ -478,19 +480,19 @@ class Remangler {
478
480
479
481
class TargetTypeReplacements {
480
482
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 ;
483
485
484
486
void CreateRemangledTypeReplacements () {
485
487
// RemangleTypes which are not aliases or not the exact same alias type
486
488
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 ()] =
490
492
TypeReplacementPair.getSecond ();
491
- else if (AliasTypeReplacements [TypeReplacementPair.getFirst ()] !=
493
+ else if (CloneTypeReplacements [TypeReplacementPair.getFirst ()] !=
492
494
TypeReplacementPair.getSecond ())
493
- RemangledAliasTypeReplacements [TypeReplacementPair.getFirst ()] =
495
+ RemangledCloneTypeReplacements [TypeReplacementPair.getFirst ()] =
494
496
TypeReplacementPair.getSecond ();
495
497
}
496
498
@@ -503,22 +505,22 @@ class TargetTypeReplacements {
503
505
// Replace char with signed char
504
506
ParameterTypeReplacements[" char" ] = " signed char" ;
505
507
506
- // Make replaced long functions aliases to either integer or long long
508
+ // Make replaced long functions clones of either integer or long long
507
509
// variant
508
510
if (LongWidth == SupportedLongWidth::L32) {
509
- AliasTypeReplacements [" long" ] = " int" ;
510
- AliasTypeReplacements [" unsigned long" ] = " unsigned int" ;
511
+ CloneTypeReplacements [" long" ] = " int" ;
512
+ CloneTypeReplacements [" unsigned long" ] = " unsigned int" ;
511
513
} 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" ;
514
516
}
515
517
516
- // Make replaced char functions aliases to either integer or long long
518
+ // Make replaced char functions clones of either integer or long long
517
519
// variant
518
520
if (CharSignedness == Signedness::Signed) {
519
- AliasTypeReplacements [" char" ] = " signed char" ;
521
+ CloneTypeReplacements [" char" ] = " signed char" ;
520
522
} else {
521
- AliasTypeReplacements [" char" ] = " unsigned char" ;
523
+ CloneTypeReplacements [" char" ] = " unsigned char" ;
522
524
}
523
525
524
526
CreateRemangledTypeReplacements ();
@@ -528,21 +530,21 @@ class TargetTypeReplacements {
528
530
return ParameterTypeReplacements;
529
531
}
530
532
531
- SmallDenseMap<const char *, const char *> getAliasTypeReplacements () {
532
- return AliasTypeReplacements ;
533
+ SmallDenseMap<const char *, const char *> getCloneTypeReplacements () {
534
+ return CloneTypeReplacements ;
533
535
}
534
536
535
537
SmallDenseMap<const char *, const char *>
536
- getRemangledAliasTypeReplacements () {
537
- return RemangledAliasTypeReplacements ;
538
+ getRemangledCloneTypeReplacements () {
539
+ return RemangledCloneTypeReplacements ;
538
540
}
539
541
};
540
542
541
- bool createAliasFromMap (
543
+ bool createCloneFromMap (
542
544
Module *M, std::string originalName,
543
545
const itanium_demangle::Node *functionTree,
544
546
SmallDenseMap<const char *, const char *> TypeReplacements,
545
- bool AliaseeTypeReplacement = false ) {
547
+ bool CloneeTypeReplacement = false ) {
546
548
Remangler ATR{functionTree, TypeReplacements};
547
549
std::string RemangledName = ATR.remangle ();
548
550
@@ -553,39 +555,41 @@ bool createAliasFromMap(
553
555
if (RemangledName == originalName)
554
556
return true ;
555
557
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;
560
562
} else {
561
- AliasName = RemangledName;
562
- AliaseeName = originalName;
563
+ CloneName = RemangledName;
564
+ CloneeName = originalName;
563
565
}
564
566
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));
568
572
} 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;
571
575
}
572
576
573
577
return true ;
574
578
}
575
579
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 ))
584
588
return false ;
585
589
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 ()))
589
593
return false ;
590
594
591
595
return true ;
@@ -621,10 +625,10 @@ bool remangleFunction(Function &func, Module *M,
621
625
}
622
626
func.setName (RemangledName);
623
627
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))
628
632
return false ;
629
633
}
630
634
@@ -661,10 +665,14 @@ int main(int argc, const char **argv) {
661
665
return 1 ;
662
666
}
663
667
664
- bool Success = true ;
668
+ std::vector<Function *> FuncList ;
665
669
for (auto &Func : M->getFunctionList ())
666
- Success = remangleFunction (Func, M. get (), Replacements) && Success ;
670
+ FuncList. push_back (&Func) ;
667
671
672
+ bool Success = true ;
673
+ for (auto Func : FuncList) {
674
+ Success = remangleFunction (*Func, M.get (), Replacements) && Success;
675
+ }
668
676
// Only fail after all to give as much context as possible.
669
677
if (!Success) {
670
678
errs () << " Failed to remangle all mangled functions in module.\n " ;
0 commit comments