[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