diff options
author | Amaury Sechet <deadalnix@gmail.com> | 2016-02-17 22:13:33 +0000 |
---|---|---|
committer | Amaury Sechet <deadalnix@gmail.com> | 2016-02-17 22:13:33 +0000 |
commit | e8ba2bfd5d9715752c06a6b2a825b1aded3329ab (patch) | |
tree | 8b23043da4251e1da978f9c4a9caede678be02da /llvm/tools/llvm-c-test/echo.cpp | |
parent | b636b904c229f02d574a27b3f6f2a41c39a1d541 (diff) | |
download | bcm5719-llvm-e8ba2bfd5d9715752c06a6b2a825b1aded3329ab.tar.gz bcm5719-llvm-e8ba2bfd5d9715752c06a6b2a825b1aded3329ab.zip |
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
llvm-svn: 261164
Diffstat (limited to 'llvm/tools/llvm-c-test/echo.cpp')
-rw-r--r-- | llvm/tools/llvm-c-test/echo.cpp | 170 |
1 files changed, 138 insertions, 32 deletions
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp index 8ff75fb6de5..b926c8124f0 100644 --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -221,22 +221,57 @@ LLVMValueRef clone_constant(LLVMValueRef Cst, LLVMModuleRef M) { 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"); + + Cur = Next; + } -static void clone_functions(LLVMModuleRef Src, LLVMModuleRef Dst) { - LLVMValueRef Begin = LLVMGetFirstFunction(Src); - LLVMValueRef End = LLVMGetLastFunction(Src); + 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(LLVMModuleRef Src, LLVMModuleRef Dst) { 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); |