[llvm] r261164 - Add support for global variables in the C API echo test
Amaury Sechet via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 17 14:13:33 PST 2016
Author: deadalnix
Date: Wed Feb 17 16:13:33 2016
New Revision: 261164
URL: http://llvm.org/viewvc/llvm-project?rev=261164&view=rev
Log:
Add support for global variables in the C API echo test
Summary: As per title
Reviewers: bogner, chandlerc, echristo, dblaikie, joker.eph, Wallbraker
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D17249
Modified:
llvm/trunk/test/Bindings/llvm-c/echo.ll
llvm/trunk/tools/llvm-c-test/echo.cpp
Modified: llvm/trunk/test/Bindings/llvm-c/echo.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/llvm-c/echo.ll?rev=261164&r1=261163&r2=261164&view=diff
==============================================================================
--- llvm/trunk/test/Bindings/llvm-c/echo.ll (original)
+++ llvm/trunk/test/Bindings/llvm-c/echo.ll Wed Feb 17 16:13:33 2016
@@ -7,6 +7,15 @@ target triple = "x86_64-apple-macosx10.1
%S = type { i64, %S* }
+ at var = global i32 42
+ at ext = external global i32*
+ at cst = constant %S { i64 1, %S* @cst }
+ at tl = thread_local global { i64, %S* } { i64 1, %S* @cst }
+ at hidden = hidden global i32 7
+ at protected = protected global i32 23
+ at section = global i32 27, section ".custom"
+ at align = global i32 31, align 4
+
define { i64, %S* } @unpackrepack(%S %s) {
%1 = extractvalue %S %s, 0
%2 = extractvalue %S %s, 1
Modified: llvm/trunk/tools/llvm-c-test/echo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-c-test/echo.cpp?rev=261164&r1=261163&r2=261164&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-c-test/echo.cpp (original)
+++ llvm/trunk/tools/llvm-c-test/echo.cpp Wed Feb 17 16:13:33 2016
@@ -221,22 +221,57 @@ LLVMValueRef clone_constant(LLVMValueRef
const char *Name = LLVMGetValueName(Cst);
// Try function
- if (LLVMIsAFunction(Cst))
- return LLVMGetNamedFunction(M, Name);
+ if (LLVMIsAFunction(Cst)) {
+ LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
+ if (Dst)
+ return Dst;
+ report_fatal_error("Could not find function");
+ }
// Try global variable
- if (LLVMIsAGlobalVariable(Cst))
- return LLVMGetNamedGlobal(M, Name);
+ if (LLVMIsAGlobalVariable(Cst)) {
+ LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
+ if (Dst)
+ return Dst;
+ report_fatal_error("Could not find function");
+ }
fprintf(stderr, "Could not find @%s\n", Name);
exit(-1);
}
- // Try literal
+ // Try integer literal
if (LLVMIsAConstantInt(Cst))
return LLVMConstInt(TypeCloner(M).Clone(Cst),
LLVMConstIntGetZExtValue(Cst), false);
+ // Try zeroinitializer
+ if (LLVMIsAConstantAggregateZero(Cst))
+ return LLVMConstNull(TypeCloner(M).Clone(Cst));
+
+ // Try constant array
+ if (LLVMIsAConstantArray(Cst)) {
+ LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
+ unsigned EltCount = LLVMGetArrayLength(Ty);
+ SmallVector<LLVMValueRef, 8> Elts;
+ for (unsigned i = 0; i < EltCount; i++)
+ Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
+ return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
+ }
+
+ // Try constant struct
+ if (LLVMIsAConstantStruct(Cst)) {
+ LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
+ unsigned EltCount = LLVMCountStructElementTypes(Ty);
+ SmallVector<LLVMValueRef, 8> Elts;
+ for (unsigned i = 0; i < EltCount; i++)
+ Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
+ if (LLVMGetStructName(Ty))
+ return LLVMConstNamedStruct(Ty, Elts.data(), EltCount);
+ return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(),
+ EltCount, LLVMIsPackedStruct(Ty));
+ }
+
// Try undef
if (LLVMIsUndef(Cst))
return LLVMGetUndef(TypeCloner(M).Clone(Cst));
@@ -587,40 +622,53 @@ struct FunCloner {
}
};
-static void clone_function(LLVMValueRef Src, LLVMModuleRef M) {
- const char *Name = LLVMGetValueName(Src);
- LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
- if (!Fun)
- report_fatal_error("Function must have been declared already");
+static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
+ LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
+ LLVMValueRef End = LLVMGetLastGlobal(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no begining");
+ return;
+ }
- FunCloner FC(Src, Fun);
- FC.CloneBBs(Src);
-}
+ LLVMValueRef Cur = Begin;
+ LLVMValueRef Next = nullptr;
+ while (true) {
+ const char *Name = LLVMGetValueName(Cur);
+ if (LLVMGetNamedGlobal(M, Name))
+ report_fatal_error("GlobalVariable already cloned");
+ LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name);
-static void declare_function(LLVMValueRef Src, LLVMModuleRef M) {
- const char *Name = LLVMGetValueName(Src);
- LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
- if (Fun != nullptr)
- report_fatal_error("Function already cloned");
+ Next = LLVMGetNextGlobal(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("");
+ break;
+ }
- LLVMTypeRef FunTy = LLVMGetElementType(TypeCloner(M).Clone(Src));
- LLVMAddFunction(M, Name, FunTy);
-}
+ LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous global is not Current");
-static void clone_functions(LLVMModuleRef Src, LLVMModuleRef Dst) {
- LLVMValueRef Begin = LLVMGetFirstFunction(Src);
- LLVMValueRef End = LLVMGetLastFunction(Src);
+ Cur = Next;
+ }
+
+ Begin = LLVMGetFirstFunction(Src);
+ End = LLVMGetLastFunction(Src);
if (!Begin) {
if (End != nullptr)
- report_fatal_error("Range has an end but no start");
+ report_fatal_error("Range has an end but no begining");
return;
}
- // First pass, we declare all function
- LLVMValueRef Cur = Begin;
- LLVMValueRef Next = nullptr;
+ Cur = Begin;
+ Next = nullptr;
while (true) {
- declare_function(Cur, Dst);
+ const char *Name = LLVMGetValueName(Cur);
+ if (LLVMGetNamedFunction(M, Name))
+ report_fatal_error("Function already cloned");
+ LLVMAddFunction(M, Name, LLVMGetElementType(TypeCloner(M).Clone(Cur)));
+
Next = LLVMGetNextFunction(Cur);
if (Next == nullptr) {
if (Cur != End)
@@ -634,12 +682,69 @@ static void clone_functions(LLVMModuleRe
Cur = Next;
}
+}
+
+static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
+ LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
+ LLVMValueRef End = LLVMGetLastGlobal(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no begining");
+ return;
+ }
+
+ LLVMValueRef Cur = Begin;
+ LLVMValueRef Next = nullptr;
+ while (true) {
+ const char *Name = LLVMGetValueName(Cur);
+ LLVMValueRef G = LLVMGetNamedGlobal(M, Name);
+ if (!G)
+ report_fatal_error("GlobalVariable must have been declared already");
+
+ if (auto I = LLVMGetInitializer(Cur))
+ LLVMSetInitializer(G, clone_constant(I, M));
+
+ LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur));
+ LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur));
+ LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur));
+ LLVMSetLinkage(G, LLVMGetLinkage(Cur));
+ LLVMSetSection(G, LLVMGetSection(Cur));
+ LLVMSetVisibility(G, LLVMGetVisibility(Cur));
+ LLVMSetUnnamedAddr(G, LLVMHasUnnamedAddr(Cur));
+ LLVMSetAlignment(G, LLVMGetAlignment(Cur));
+
+ Next = LLVMGetNextGlobal(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous global is not Current");
+
+ Cur = Next;
+ }
+
+ Begin = LLVMGetFirstFunction(Src);
+ End = LLVMGetLastFunction(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no begining");
+ return;
+ }
- // Second pass, we define them
Cur = Begin;
Next = nullptr;
while (true) {
- clone_function(Cur, Dst);
+ const char *Name = LLVMGetValueName(Cur);
+ LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
+ if (!Fun)
+ report_fatal_error("Function must have been declared already");
+ FunCloner FC(Cur, Fun);
+ FC.CloneBBs(Cur);
+
Next = LLVMGetNextFunction(Cur);
if (Next == nullptr) {
if (Cur != End)
@@ -668,7 +773,8 @@ int llvm_echo(void) {
if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src)))
report_fatal_error("Inconsistent DataLayout string representation");
- clone_functions(Src, M);
+ declare_symbols(Src, M);
+ clone_symbols(Src, M);
char *Str = LLVMPrintModuleToString(M);
fputs(Str, stdout);
More information about the llvm-commits
mailing list