[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
This commit is contained in:
Robert Widmann 2018-05-20 23:49:08 +00:00
parent 55b4067350
commit 360d6e35e6
4 changed files with 189 additions and 6 deletions

View File

@ -2117,6 +2117,56 @@ void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit);
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);
/**
* @}
*/

View File

@ -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,

View File

@ -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

View File

@ -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) {