Skip to content

Commit 1181c40

Browse files
committed
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332826 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent aa228ef commit 1181c40

File tree

4 files changed

+189
-6
lines changed

4 files changed

+189
-6
lines changed

include/llvm-c/Core.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,6 +2117,56 @@ void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit);
21172117
LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
21182118
const char *Name);
21192119

2120+
/**
2121+
* Obtain a GlobalAlias value from a Module by its name.
2122+
*
2123+
* The returned value corresponds to a llvm::GlobalAlias value.
2124+
*
2125+
* @see llvm::Module::getNamedAlias()
2126+
*/
2127+
LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M,
2128+
const char *Name, size_t NameLen);
2129+
2130+
/**
2131+
* Obtain an iterator to the first GlobalAlias in a Module.
2132+
*
2133+
* @see llvm::Module::alias_begin()
2134+
*/
2135+
LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M);
2136+
2137+
/**
2138+
* Obtain an iterator to the last GlobalAlias in a Module.
2139+
*
2140+
* @see llvm::Module::alias_end()
2141+
*/
2142+
LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M);
2143+
2144+
/**
2145+
* Advance a GlobalAlias iterator to the next GlobalAlias.
2146+
*
2147+
* Returns NULL if the iterator was already at the end and there are no more
2148+
* global aliases.
2149+
*/
2150+
LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA);
2151+
2152+
/**
2153+
* Decrement a GlobalAlias iterator to the previous GlobalAlias.
2154+
*
2155+
* Returns NULL if the iterator was already at the beginning and there are
2156+
* no previous global aliases.
2157+
*/
2158+
LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA);
2159+
2160+
/**
2161+
* Retrieve the target value of an alias.
2162+
*/
2163+
LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias);
2164+
2165+
/**
2166+
* Set the target value of an alias.
2167+
*/
2168+
void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee);
2169+
21202170
/**
21212171
* @}
21222172
*/

lib/IR/Core.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,6 +1965,51 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee,
19651965
unwrap<Constant>(Aliasee), unwrap(M)));
19661966
}
19671967

1968+
LLVMValueRef LLVMGetNamedGlobalAlias(LLVMModuleRef M,
1969+
const char *Name, size_t NameLen) {
1970+
return wrap(unwrap(M)->getNamedAlias(Name));
1971+
}
1972+
1973+
LLVMValueRef LLVMGetFirstGlobalAlias(LLVMModuleRef M) {
1974+
Module *Mod = unwrap(M);
1975+
Module::alias_iterator I = Mod->alias_begin();
1976+
if (I == Mod->alias_end())
1977+
return nullptr;
1978+
return wrap(&*I);
1979+
}
1980+
1981+
LLVMValueRef LLVMGetLastGlobalAlias(LLVMModuleRef M) {
1982+
Module *Mod = unwrap(M);
1983+
Module::alias_iterator I = Mod->alias_end();
1984+
if (I == Mod->alias_begin())
1985+
return nullptr;
1986+
return wrap(&*--I);
1987+
}
1988+
1989+
LLVMValueRef LLVMGetNextGlobalAlias(LLVMValueRef GA) {
1990+
GlobalAlias *Alias = unwrap<GlobalAlias>(GA);
1991+
Module::alias_iterator I(Alias);
1992+
if (++I == Alias->getParent()->alias_end())
1993+
return nullptr;
1994+
return wrap(&*I);
1995+
}
1996+
1997+
LLVMValueRef LLVMGetPreviousGlobalAlias(LLVMValueRef GA) {
1998+
GlobalAlias *Alias = unwrap<GlobalAlias>(GA);
1999+
Module::alias_iterator I(Alias);
2000+
if (I == Alias->getParent()->alias_begin())
2001+
return nullptr;
2002+
return wrap(&*--I);
2003+
}
2004+
2005+
LLVMValueRef LLVMAliasGetAliasee(LLVMValueRef Alias) {
2006+
return wrap(unwrap<GlobalAlias>(Alias)->getAliasee());
2007+
}
2008+
2009+
void LLVMAliasSetAliasee(LLVMValueRef Alias, LLVMValueRef Aliasee) {
2010+
unwrap<GlobalAlias>(Alias)->setAliasee(unwrap<Constant>(Aliasee));
2011+
}
2012+
19682013
/*--.. Operations on functions .............................................--*/
19692014

19702015
LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,

test/Bindings/llvm-c/echo.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ module asm "classical GAS"
2222
@section = global i32 27, section ".custom"
2323
@align = global i32 31, align 4
2424

25+
@aliased1 = alias i32, i32* @var
26+
@aliased2 = internal alias i32, i32* @var
27+
@aliased3 = external alias i32, i32* @var
28+
@aliased4 = weak alias i32, i32* @var
29+
@aliased5 = weak_odr alias i32, i32* @var
30+
2531
define { i64, %S* } @unpackrepack(%S %s) {
2632
%1 = extractvalue %S %s, 0
2733
%2 = extractvalue %S %s, 1

tools/llvm-c-test/echo.cpp

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,19 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) {
248248
// Try global variable
249249
if (LLVMIsAGlobalVariable(Cst)) {
250250
check_value_kind(Cst, LLVMGlobalVariableValueKind);
251-
LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
251+
LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
252252
if (Dst)
253253
return Dst;
254-
report_fatal_error("Could not find function");
254+
report_fatal_error("Could not find variable");
255+
}
256+
257+
// Try global alias
258+
if (LLVMIsAGlobalAlias(Cst)) {
259+
check_value_kind(Cst, LLVMGlobalAliasValueKind);
260+
LLVMValueRef Dst = LLVMGetNamedGlobalAlias(M, Name, NameLen);
261+
if (Dst)
262+
return Dst;
263+
report_fatal_error("Could not find alias");
255264
}
256265

257266
fprintf(stderr, "Could not find @%s\n", Name);
@@ -822,6 +831,8 @@ struct FunCloner {
822831
};
823832

824833
static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
834+
auto Ctx = LLVMGetModuleContext(M);
835+
825836
LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
826837
LLVMValueRef End = LLVMGetLastGlobal(Src);
827838

@@ -860,11 +871,9 @@ static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
860871
if (!Begin) {
861872
if (End != nullptr)
862873
report_fatal_error("Range has an end but no beginning");
863-
return;
874+
goto AliasDecl;
864875
}
865876

866-
auto Ctx = LLVMGetModuleContext(M);
867-
868877
Cur = Begin;
869878
Next = nullptr;
870879
while (true) {
@@ -900,6 +909,40 @@ static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
900909

901910
Cur = Next;
902911
}
912+
913+
AliasDecl:
914+
Begin = LLVMGetFirstGlobalAlias(Src);
915+
End = LLVMGetLastGlobalAlias(Src);
916+
if (!Begin) {
917+
if (End != nullptr)
918+
report_fatal_error("Range has an end but no beginning");
919+
return;
920+
}
921+
922+
Cur = Begin;
923+
Next = nullptr;
924+
while (true) {
925+
size_t NameLen;
926+
const char *Name = LLVMGetValueName2(Cur, &NameLen);
927+
if (LLVMGetNamedGlobalAlias(M, Name, NameLen))
928+
report_fatal_error("Global alias already cloned");
929+
LLVMTypeRef CurType = TypeCloner(M).Clone(Cur);
930+
// FIXME: Allow NULL aliasee.
931+
LLVMAddAlias(M, CurType, LLVMGetUndef(CurType), Name);
932+
933+
Next = LLVMGetNextGlobalAlias(Cur);
934+
if (Next == nullptr) {
935+
if (Cur != End)
936+
report_fatal_error("");
937+
break;
938+
}
939+
940+
LLVMValueRef Prev = LLVMGetPreviousGlobalAlias(Next);
941+
if (Prev != Cur)
942+
report_fatal_error("Next.Previous global is not Current");
943+
944+
Cur = Next;
945+
}
903946
}
904947

905948
static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
@@ -953,7 +996,7 @@ static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
953996
if (!Begin) {
954997
if (End != nullptr)
955998
report_fatal_error("Range has an end but no beginning");
956-
return;
999+
goto AliasClone;
9571000
}
9581001

9591002
Cur = Begin;
@@ -991,6 +1034,45 @@ static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
9911034

9921035
Cur = Next;
9931036
}
1037+
1038+
AliasClone:
1039+
Begin = LLVMGetFirstGlobalAlias(Src);
1040+
End = LLVMGetLastGlobalAlias(Src);
1041+
if (!Begin) {
1042+
if (End != nullptr)
1043+
report_fatal_error("Range has an end but no beginning");
1044+
return;
1045+
}
1046+
1047+
Cur = Begin;
1048+
Next = nullptr;
1049+
while (true) {
1050+
size_t NameLen;
1051+
const char *Name = LLVMGetValueName2(Cur, &NameLen);
1052+
LLVMValueRef Alias = LLVMGetNamedGlobalAlias(M, Name, NameLen);
1053+
if (!Alias)
1054+
report_fatal_error("Global alias must have been declared already");
1055+
1056+
if (LLVMValueRef Aliasee = LLVMAliasGetAliasee(Cur)) {
1057+
LLVMAliasSetAliasee(Alias, clone_constant(Aliasee, M));
1058+
}
1059+
1060+
LLVMSetLinkage(Alias, LLVMGetLinkage(Cur));
1061+
LLVMSetUnnamedAddress(Alias, LLVMGetUnnamedAddress(Cur));
1062+
1063+
Next = LLVMGetNextGlobalAlias(Cur);
1064+
if (Next == nullptr) {
1065+
if (Cur != End)
1066+
report_fatal_error("Last global alias does not match End");
1067+
break;
1068+
}
1069+
1070+
LLVMValueRef Prev = LLVMGetPreviousGlobalAlias(Next);
1071+
if (Prev != Cur)
1072+
report_fatal_error("Next.Previous global alias is not Current");
1073+
1074+
Cur = Next;
1075+
}
9941076
}
9951077

9961078
int llvm_echo(void) {

0 commit comments

Comments
 (0)