diff options
author | Robert Widmann <devteam.codafi@gmail.com> | 2018-05-20 23:49:08 +0000 |
---|---|---|
committer | Robert Widmann <devteam.codafi@gmail.com> | 2018-05-20 23:49:08 +0000 |
commit | 360d6e35e695c54078f37fa7806f562e8e08ff62 (patch) | |
tree | 74ad00d4ee708d8861450e91f84c53e931a02d8e | |
parent | 55b40673505b8786a77d55f6541c944ba8238f4c (diff) | |
download | bcm5719-llvm-360d6e35e695c54078f37fa7806f562e8e08ff62.tar.gz bcm5719-llvm-360d6e35e695c54078f37fa7806f562e8e08ff62.zip |
[LLVM-C] Improve Bindings For Aliases
Summary: Add wrappers for a module's alias iterators and a getter and setter for the aliasee value.
Reviewers: whitequark, deadalnix
Reviewed By: whitequark
Subscribers: llvm-commits, harlanhaskins
Differential Revision: https://reviews.llvm.org/D46808
llvm-svn: 332826
-rw-r--r-- | llvm/include/llvm-c/Core.h | 50 | ||||
-rw-r--r-- | llvm/lib/IR/Core.cpp | 45 | ||||
-rw-r--r-- | llvm/test/Bindings/llvm-c/echo.ll | 6 | ||||
-rw-r--r-- | llvm/tools/llvm-c-test/echo.cpp | 94 |
4 files changed, 189 insertions, 6 deletions
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 6f1db314ece..6792219f873 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -2118,6 +2118,56 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, const char *Name); /** + * Obtain a GlobalAlias value from a Module by its name. + * + * The returned value corresponds to a llvm::GlobalAlias value. + * + * @see llvm::Module::getNamedAlias() + */ +LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M, + const char *Name, size_t NameLen); + +/** + * Obtain an iterator to the first GlobalAlias in a Module. + * + * @see llvm::Module::alias_begin() + */ +LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M); + +/** + * Obtain an iterator to the last GlobalAlias in a Module. + * + * @see llvm::Module::alias_end() + */ +LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M); + +/** + * Advance a GlobalAlias iterator to the next GlobalAlias. + * + * Returns NULL if the iterator was already at the end and there are no more + * global aliases. + */ +LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA); + +/** + * Decrement a GlobalAlias iterator to the previous GlobalAlias. + * + * Returns NULL if the iterator was already at the beginning and there are + * no previous global aliases. + */ +LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA); + +/** + * Retrieve the target value of an alias. + */ +LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias); + +/** + * Set the target value of an alias. + */ +void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee); + +/** * @} */ diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 33dbf4af65b..bea4dee15c1 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -1965,6 +1965,51 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, unwrap<Constant>(Aliasee), unwrap(M))); } +LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M, + const char *Name, size_t NameLen) { + return wrap(unwrap(M)->getNamedAlias(Name)); +} + +LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M) { + Module *Mod = unwrap(M); + Module::alias_iterator I = Mod->alias_begin(); + if (I == Mod->alias_end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M) { + Module *Mod = unwrap(M); + Module::alias_iterator I = Mod->alias_end(); + if (I == Mod->alias_begin()) + return nullptr; + return wrap(&*--I); +} + +LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA) { + GlobalAlias *Alias = unwrap<GlobalAlias>(GA); + Module::alias_iterator I(Alias); + if (++I == Alias->getParent()->alias_end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA) { + GlobalAlias *Alias = unwrap<GlobalAlias>(GA); + Module::alias_iterator I(Alias); + if (I == Alias->getParent()->alias_begin()) + return nullptr; + return wrap(&*--I); +} + +LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias) { + return wrap(unwrap<GlobalAlias>(Alias)->getAliasee()); +} + +void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee) { + unwrap<GlobalAlias>(Alias)->setAliasee(unwrap<Constant>(Aliasee)); +} + /*--.. Operations on functions .............................................--*/ LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll index 071cbe8934f..e1052595b9d 100644 --- a/llvm/test/Bindings/llvm-c/echo.ll +++ b/llvm/test/Bindings/llvm-c/echo.ll @@ -22,6 +22,12 @@ module asm "classical GAS" @section = global i32 27, section ".custom" @align = global i32 31, align 4 +@aliased1 = alias i32, i32* @var +@aliased2 = internal alias i32, i32* @var +@aliased3 = external alias i32, i32* @var +@aliased4 = weak alias i32, i32* @var +@aliased5 = weak_odr alias i32, i32* @var + define { i64, %S* } @unpackrepack(%S %s) { %1 = extractvalue %S %s, 0 %2 = extractvalue %S %s, 1 diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp index ca3a1be0684..a9cd4cf5cbb 100644 --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -248,10 +248,19 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) { // Try global variable if (LLVMIsAGlobalVariable(Cst)) { check_value_kind(Cst, LLVMGlobalVariableValueKind); - LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name); + LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name); if (Dst) return Dst; - report_fatal_error("Could not find function"); + report_fatal_error("Could not find variable"); + } + + // Try global alias + if (LLVMIsAGlobalAlias(Cst)) { + check_value_kind(Cst, LLVMGlobalAliasValueKind); + LLVMValueRef Dst = LLVMGetNamedGlobalAlias(M, Name, NameLen); + if (Dst) + return Dst; + report_fatal_error("Could not find alias"); } fprintf(stderr, "Could not find @%s\n", Name); @@ -822,6 +831,8 @@ struct FunCloner { }; static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) { + auto Ctx = LLVMGetModuleContext(M); + LLVMValueRef Begin = LLVMGetFirstGlobal(Src); LLVMValueRef End = LLVMGetLastGlobal(Src); @@ -860,11 +871,9 @@ FunDecl: if (!Begin) { if (End != nullptr) report_fatal_error("Range has an end but no beginning"); - return; + goto AliasDecl; } - auto Ctx = LLVMGetModuleContext(M); - Cur = Begin; Next = nullptr; while (true) { @@ -900,6 +909,40 @@ FunDecl: Cur = Next; } + +AliasDecl: + Begin = LLVMGetFirstGlobalAlias(Src); + End = LLVMGetLastGlobalAlias(Src); + if (!Begin) { + if (End != nullptr) + report_fatal_error("Range has an end but no beginning"); + return; + } + + Cur = Begin; + Next = nullptr; + while (true) { + size_t NameLen; + const char *Name = LLVMGetValueName2(Cur, &NameLen); + if (LLVMGetNamedGlobalAlias(M, Name, NameLen)) + report_fatal_error("Global alias already cloned"); + LLVMTypeRef CurType = TypeCloner(M).Clone(Cur); + // FIXME: Allow NULL aliasee. + LLVMAddAlias(M, CurType, LLVMGetUndef(CurType), Name); + + Next = LLVMGetNextGlobalAlias(Cur); + if (Next == nullptr) { + if (Cur != End) + report_fatal_error(""); + break; + } + + LLVMValueRef Prev = LLVMGetPreviousGlobalAlias(Next); + if (Prev != Cur) + report_fatal_error("Next.Previous global is not Current"); + + Cur = Next; + } } static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) { @@ -953,7 +996,7 @@ FunClone: if (!Begin) { if (End != nullptr) report_fatal_error("Range has an end but no beginning"); - return; + goto AliasClone; } Cur = Begin; @@ -991,6 +1034,45 @@ FunClone: Cur = Next; } + +AliasClone: + Begin = LLVMGetFirstGlobalAlias(Src); + End = LLVMGetLastGlobalAlias(Src); + if (!Begin) { + if (End != nullptr) + report_fatal_error("Range has an end but no beginning"); + return; + } + + Cur = Begin; + Next = nullptr; + while (true) { + size_t NameLen; + const char *Name = LLVMGetValueName2(Cur, &NameLen); + LLVMValueRef Alias = LLVMGetNamedGlobalAlias(M, Name, NameLen); + if (!Alias) + report_fatal_error("Global alias must have been declared already"); + + if (LLVMValueRef Aliasee = LLVMAliasGetAliasee(Cur)) { + LLVMAliasSetAliasee(Alias, clone_constant(Aliasee, M)); + } + + LLVMSetLinkage(Alias, LLVMGetLinkage(Cur)); + LLVMSetUnnamedAddress(Alias, LLVMGetUnnamedAddress(Cur)); + + Next = LLVMGetNextGlobalAlias(Cur); + if (Next == nullptr) { + if (Cur != End) + report_fatal_error("Last global alias does not match End"); + break; + } + + LLVMValueRef Prev = LLVMGetPreviousGlobalAlias(Next); + if (Prev != Cur) + report_fatal_error("Next.Previous global alias is not Current"); + + Cur = Next; + } } int llvm_echo(void) { |