diff --git a/libclc/utils/libclc-remangler/CMakeLists.txt b/libclc/utils/libclc-remangler/CMakeLists.txt index 4db9cc74d6845..7101129d6825f 100644 --- a/libclc/utils/libclc-remangler/CMakeLists.txt +++ b/libclc/utils/libclc-remangler/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS Core Demangle Support + TransformUtils ) add_clang_tool(libclc-remangler LibclcRemangler.cpp) diff --git a/libclc/utils/libclc-remangler/LibclcRemangler.cpp b/libclc/utils/libclc-remangler/LibclcRemangler.cpp index dc172cce2b9c2..788c07800ef43 100644 --- a/libclc/utils/libclc-remangler/LibclcRemangler.cpp +++ b/libclc/utils/libclc-remangler/LibclcRemangler.cpp @@ -11,28 +11,28 @@ // `unsigned long`, and `char` to appear as if they use `long long`, // `unsigned long long`, and `signed char`, as is consistent with the primitive // types defined by OpenCL C. Following a remangling, the original function -// mangling will be made an alias to either the remangled function or a function -// with a suitable function if any exists. In some cases an alias of the -// remangled function is created for functions where multiple parameters have -// been replaced, and the replaced values are aliases. +// mangling will be built as a clone of either the remangled function or a +// function with a suitable function if any exists. In some cases a clone of +// the remangled function is created for functions where multiple parameters +// have been replaced, and the replaced values are aliases. // -// Original Alias Example: +// Original Clone Example: // If libclc defined a function `f(long)` the mangled name would be // `_Z1fl`. The remangler would rename this function to `_Z1fx` -// (`f(long long)`.) If the target uses 64-bit `long`, `_Z1fl` is made -// an alias to the old function now under the name `_Z1fx`, whereas if -// the target uses 32-bit `long`, `_Z1fl` is made an alias to `_Z1fi` +// (`f(long long)`.) If the target uses 64-bit `long`, `_Z1fl` is +// cloned from the old function now under the name `_Z1fx`, whereas if +// the target uses 32-bit `long`, `_Z1fl` is cloned from `_Z1fi` // (`f(int)`) if such a function exists. // -// Remangled Alias Example: +// Remangled Clone Example: // In cases where the remangled name squashes valid versions of a -// function an alias is created. `f(long, char, signed char)` would be +// function a clone is created. `f(long, char, signed char)` would be // mangled to // `_Z1flca`. The remangler would rename this function to `_Z1fyaa` // (`f(long long, signed char, signed char)`). If the target uses a -// signed char then a valid alias `_Z1fyca`, +// signed char then a valid clone `_Z1fyca`, // (`f(long long, char, signed char)`), is not defined. The remangler -// creates an alias of the renamed function,`_Z1fyaa` , to this +// creates a clone of the renamed function,`_Z1fyaa` , to this // permutation, `_Z1fyca`. // //===----------------------------------------------------------------------===// @@ -58,6 +58,8 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/ValueMapper.h" #include #include @@ -153,7 +155,7 @@ class DefaultAllocator { public: void reset() { Alloc.reset(); } - template T *makeNode(Args &&... args) { + template T *makeNode(Args &&...args) { return new (Alloc.allocate(sizeof(T))) T(std::forward(args)...); } @@ -478,19 +480,19 @@ class Remangler { class TargetTypeReplacements { SmallDenseMap ParameterTypeReplacements; - SmallDenseMap AliasTypeReplacements; - SmallDenseMap RemangledAliasTypeReplacements; + SmallDenseMap CloneTypeReplacements; + SmallDenseMap RemangledCloneTypeReplacements; void CreateRemangledTypeReplacements() { // RemangleTypes which are not aliases or not the exact same alias type for (auto &TypeReplacementPair : ParameterTypeReplacements) - if (AliasTypeReplacements.find(TypeReplacementPair.getFirst()) == - AliasTypeReplacements.end()) - RemangledAliasTypeReplacements[TypeReplacementPair.getFirst()] = + if (CloneTypeReplacements.find(TypeReplacementPair.getFirst()) == + CloneTypeReplacements.end()) + RemangledCloneTypeReplacements[TypeReplacementPair.getFirst()] = TypeReplacementPair.getSecond(); - else if (AliasTypeReplacements[TypeReplacementPair.getFirst()] != + else if (CloneTypeReplacements[TypeReplacementPair.getFirst()] != TypeReplacementPair.getSecond()) - RemangledAliasTypeReplacements[TypeReplacementPair.getFirst()] = + RemangledCloneTypeReplacements[TypeReplacementPair.getFirst()] = TypeReplacementPair.getSecond(); } @@ -503,22 +505,22 @@ class TargetTypeReplacements { // Replace char with signed char ParameterTypeReplacements["char"] = "signed char"; - // Make replaced long functions aliases to either integer or long long + // Make replaced long functions clones of either integer or long long // variant if (LongWidth == SupportedLongWidth::L32) { - AliasTypeReplacements["long"] = "int"; - AliasTypeReplacements["unsigned long"] = "unsigned int"; + CloneTypeReplacements["long"] = "int"; + CloneTypeReplacements["unsigned long"] = "unsigned int"; } else { - AliasTypeReplacements["long"] = "long long"; - AliasTypeReplacements["unsigned long"] = "unsigned long long"; + CloneTypeReplacements["long"] = "long long"; + CloneTypeReplacements["unsigned long"] = "unsigned long long"; } - // Make replaced char functions aliases to either integer or long long + // Make replaced char functions clones of either integer or long long // variant if (CharSignedness == Signedness::Signed) { - AliasTypeReplacements["char"] = "signed char"; + CloneTypeReplacements["char"] = "signed char"; } else { - AliasTypeReplacements["char"] = "unsigned char"; + CloneTypeReplacements["char"] = "unsigned char"; } CreateRemangledTypeReplacements(); @@ -528,21 +530,21 @@ class TargetTypeReplacements { return ParameterTypeReplacements; } - SmallDenseMap getAliasTypeReplacements() { - return AliasTypeReplacements; + SmallDenseMap getCloneTypeReplacements() { + return CloneTypeReplacements; } SmallDenseMap - getRemangledAliasTypeReplacements() { - return RemangledAliasTypeReplacements; + getRemangledCloneTypeReplacements() { + return RemangledCloneTypeReplacements; } }; -bool createAliasFromMap( +bool createCloneFromMap( Module *M, std::string originalName, const itanium_demangle::Node *functionTree, SmallDenseMap TypeReplacements, - bool AliaseeTypeReplacement = false) { + bool CloneeTypeReplacement = false) { Remangler ATR{functionTree, TypeReplacements}; std::string RemangledName = ATR.remangle(); @@ -553,39 +555,41 @@ bool createAliasFromMap( if (RemangledName == originalName) return true; - StringRef AliasName, AliaseeName; - if (AliaseeTypeReplacement) { - AliasName = originalName; - AliaseeName = RemangledName; + StringRef CloneName, CloneeName; + if (CloneeTypeReplacement) { + CloneName = originalName; + CloneeName = RemangledName; } else { - AliasName = RemangledName; - AliaseeName = originalName; + CloneName = RemangledName; + CloneeName = originalName; } - Function *Aliasee = M->getFunction(AliaseeName); - if (Aliasee) { - GlobalAlias::create(AliasName, Aliasee); + Function *Clonee = M->getFunction(CloneeName); + if (Clonee) { + ValueToValueMapTy Dummy; + Function *NewF = CloneFunction(Clonee, Dummy); + NewF->setName(std::string(CloneName)); } else if (Verbose) { - std::cout << "Could not create alias " << AliasName.data() << " : missing " - << AliaseeName.data() << std::endl; + std::cout << "Could not create copy " << CloneName.data() << " : missing " + << CloneeName.data() << std::endl; } return true; } -bool createAliases(Module *M, std::string originalMangledName, - std::string remangledName, - const itanium_demangle::Node *functionTree, - TargetTypeReplacements replacements) { - // create alias of original function - if (!createAliasFromMap(M, originalMangledName, functionTree, - replacements.getAliasTypeReplacements(), - /* AliaseeTypeReplacement= */ true)) +bool createClones(Module *M, std::string originalMangledName, + std::string remangledName, + const itanium_demangle::Node *functionTree, + TargetTypeReplacements replacements) { + // create clone of original function + if (!createCloneFromMap(M, originalMangledName, functionTree, + replacements.getCloneTypeReplacements(), + /* CloneeTypeReplacement= */ true)) return false; - // create alias from remangled function - if (!createAliasFromMap(M, remangledName, functionTree, - replacements.getRemangledAliasTypeReplacements())) + // create clone of remangled function + if (!createCloneFromMap(M, remangledName, functionTree, + replacements.getRemangledCloneTypeReplacements())) return false; return true; @@ -621,10 +625,10 @@ bool remangleFunction(Function &func, Module *M, } func.setName(RemangledName); - // Make an alias to a suitable function using the old name if there is a - // type-mapping and the corresponding aliasee function exists. - if (!createAliases(M, MangledName, RemangledName, FunctionTree, - replacements)) + // Make a clone of a suitable function using the old name if there is a + // type-mapping and the corresponding clonee function exists. + if (!createClones(M, MangledName, RemangledName, FunctionTree, + replacements)) return false; } @@ -661,10 +665,14 @@ int main(int argc, const char **argv) { return 1; } - bool Success = true; + std::vector FuncList; for (auto &Func : M->getFunctionList()) - Success = remangleFunction(Func, M.get(), Replacements) && Success; + FuncList.push_back(&Func); + bool Success = true; + for (auto Func : FuncList) { + Success = remangleFunction(*Func, M.get(), Replacements) && Success; + } // Only fail after all to give as much context as possible. if (!Success) { errs() << "Failed to remangle all mangled functions in module.\n";