llvm.org GIT mirror llvm / eef9379
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261164 91177308-0d34-0410-b5e6-96231b3b80d8 Amaury Sechet 4 years ago
2 changed file(s) with 150 addition(s) and 35 deletion(s). Raw diff Collapse all Expand all
55 target triple = "x86_64-apple-macosx10.11.0"
66
77 %S = type { i64, %S* }
8
9 @var = global i32 42
10 @ext = external global i32*
11 @cst = constant %S { i64 1, %S* @cst }
12 @tl = thread_local global { i64, %S* } { i64 1, %S* @cst }
13 @hidden = hidden global i32 7
14 @protected = protected global i32 23
15 @section = global i32 27, section ".custom"
16 @align = global i32 31, align 4
817
918 define { i64, %S* } @unpackrepack(%S %s) {
1019 %1 = extractvalue %S %s, 0
220220 const char *Name = LLVMGetValueName(Cst);
221221
222222 // Try function
223 if (LLVMIsAFunction(Cst))
224 return LLVMGetNamedFunction(M, Name);
223 if (LLVMIsAFunction(Cst)) {
224 LLVMValueRef Dst = LLVMGetNamedFunction(M, Name);
225 if (Dst)
226 return Dst;
227 report_fatal_error("Could not find function");
228 }
225229
226230 // Try global variable
227 if (LLVMIsAGlobalVariable(Cst))
228 return LLVMGetNamedGlobal(M, Name);
231 if (LLVMIsAGlobalVariable(Cst)) {
232 LLVMValueRef Dst = LLVMGetNamedGlobal(M, Name);
233 if (Dst)
234 return Dst;
235 report_fatal_error("Could not find function");
236 }
229237
230238 fprintf(stderr, "Could not find @%s\n", Name);
231239 exit(-1);
232240 }
233241
234 // Try literal
242 // Try integer literal
235243 if (LLVMIsAConstantInt(Cst))
236244 return LLVMConstInt(TypeCloner(M).Clone(Cst),
237245 LLVMConstIntGetZExtValue(Cst), false);
246
247 // Try zeroinitializer
248 if (LLVMIsAConstantAggregateZero(Cst))
249 return LLVMConstNull(TypeCloner(M).Clone(Cst));
250
251 // Try constant array
252 if (LLVMIsAConstantArray(Cst)) {
253 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
254 unsigned EltCount = LLVMGetArrayLength(Ty);
255 SmallVector Elts;
256 for (unsigned i = 0; i < EltCount; i++)
257 Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
258 return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount);
259 }
260
261 // Try constant struct
262 if (LLVMIsAConstantStruct(Cst)) {
263 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
264 unsigned EltCount = LLVMCountStructElementTypes(Ty);
265 SmallVector Elts;
266 for (unsigned i = 0; i < EltCount; i++)
267 Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M));
268 if (LLVMGetStructName(Ty))
269 return LLVMConstNamedStruct(Ty, Elts.data(), EltCount);
270 return LLVMConstStructInContext(LLVMGetModuleContext(M), Elts.data(),
271 EltCount, LLVMIsPackedStruct(Ty));
272 }
238273
239274 // Try undef
240275 if (LLVMIsUndef(Cst))
586621 }
587622 };
588623
589 static void clone_function(LLVMValueRef Src, LLVMModuleRef M) {
590 const char *Name = LLVMGetValueName(Src);
591 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
592 if (!Fun)
593 report_fatal_error("Function must have been declared already");
594
595 FunCloner FC(Src, Fun);
596 FC.CloneBBs(Src);
597 }
598
599 static void declare_function(LLVMValueRef Src, LLVMModuleRef M) {
600 const char *Name = LLVMGetValueName(Src);
601 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
602 if (Fun != nullptr)
603 report_fatal_error("Function already cloned");
604
605 LLVMTypeRef FunTy = LLVMGetElementType(TypeCloner(M).Clone(Src));
606 LLVMAddFunction(M, Name, FunTy);
607 }
608
609 static void clone_functions(LLVMModuleRef Src, LLVMModuleRef Dst) {
610 LLVMValueRef Begin = LLVMGetFirstFunction(Src);
611 LLVMValueRef End = LLVMGetLastFunction(Src);
624 static void declare_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
625 LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
626 LLVMValueRef End = LLVMGetLastGlobal(Src);
612627 if (!Begin) {
613628 if (End != nullptr)
614 report_fatal_error("Range has an end but no start");
629 report_fatal_error("Range has an end but no begining");
615630 return;
616631 }
617632
618 // First pass, we declare all function
619633 LLVMValueRef Cur = Begin;
620634 LLVMValueRef Next = nullptr;
621635 while (true) {
622 declare_function(Cur, Dst);
636 const char *Name = LLVMGetValueName(Cur);
637 if (LLVMGetNamedGlobal(M, Name))
638 report_fatal_error("GlobalVariable already cloned");
639 LLVMAddGlobal(M, LLVMGetElementType(TypeCloner(M).Clone(Cur)), Name);
640
641 Next = LLVMGetNextGlobal(Cur);
642 if (Next == nullptr) {
643 if (Cur != End)
644 report_fatal_error("");
645 break;
646 }
647
648 LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
649 if (Prev != Cur)
650 report_fatal_error("Next.Previous global is not Current");
651
652 Cur = Next;
653 }
654
655 Begin = LLVMGetFirstFunction(Src);
656 End = LLVMGetLastFunction(Src);
657 if (!Begin) {
658 if (End != nullptr)
659 report_fatal_error("Range has an end but no begining");
660 return;
661 }
662
663 Cur = Begin;
664 Next = nullptr;
665 while (true) {
666 const char *Name = LLVMGetValueName(Cur);
667 if (LLVMGetNamedFunction(M, Name))
668 report_fatal_error("Function already cloned");
669 LLVMAddFunction(M, Name, LLVMGetElementType(TypeCloner(M).Clone(Cur)));
670
623671 Next = LLVMGetNextFunction(Cur);
624672 if (Next == nullptr) {
625673 if (Cur != End)
633681
634682 Cur = Next;
635683 }
636
637 // Second pass, we define them
684 }
685
686 static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) {
687 LLVMValueRef Begin = LLVMGetFirstGlobal(Src);
688 LLVMValueRef End = LLVMGetLastGlobal(Src);
689 if (!Begin) {
690 if (End != nullptr)
691 report_fatal_error("Range has an end but no begining");
692 return;
693 }
694
695 LLVMValueRef Cur = Begin;
696 LLVMValueRef Next = nullptr;
697 while (true) {
698 const char *Name = LLVMGetValueName(Cur);
699 LLVMValueRef G = LLVMGetNamedGlobal(M, Name);
700 if (!G)
701 report_fatal_error("GlobalVariable must have been declared already");
702
703 if (auto I = LLVMGetInitializer(Cur))
704 LLVMSetInitializer(G, clone_constant(I, M));
705
706 LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur));
707 LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur));
708 LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur));
709 LLVMSetLinkage(G, LLVMGetLinkage(Cur));
710 LLVMSetSection(G, LLVMGetSection(Cur));
711 LLVMSetVisibility(G, LLVMGetVisibility(Cur));
712 LLVMSetUnnamedAddr(G, LLVMHasUnnamedAddr(Cur));
713 LLVMSetAlignment(G, LLVMGetAlignment(Cur));
714
715 Next = LLVMGetNextGlobal(Cur);
716 if (Next == nullptr) {
717 if (Cur != End)
718 report_fatal_error("");
719 break;
720 }
721
722 LLVMValueRef Prev = LLVMGetPreviousGlobal(Next);
723 if (Prev != Cur)
724 report_fatal_error("Next.Previous global is not Current");
725
726 Cur = Next;
727 }
728
729 Begin = LLVMGetFirstFunction(Src);
730 End = LLVMGetLastFunction(Src);
731 if (!Begin) {
732 if (End != nullptr)
733 report_fatal_error("Range has an end but no begining");
734 return;
735 }
736
638737 Cur = Begin;
639738 Next = nullptr;
640739 while (true) {
641 clone_function(Cur, Dst);
740 const char *Name = LLVMGetValueName(Cur);
741 LLVMValueRef Fun = LLVMGetNamedFunction(M, Name);
742 if (!Fun)
743 report_fatal_error("Function must have been declared already");
744 FunCloner FC(Cur, Fun);
745 FC.CloneBBs(Cur);
746
642747 Next = LLVMGetNextFunction(Cur);
643748 if (Next == nullptr) {
644749 if (Cur != End)
667772 if (strcmp(LLVMGetDataLayoutStr(M), LLVMGetDataLayoutStr(Src)))
668773 report_fatal_error("Inconsistent DataLayout string representation");
669774
670 clone_functions(Src, M);
775 declare_symbols(Src, M);
776 clone_symbols(Src, M);
671777 char *Str = LLVMPrintModuleToString(M);
672778 fputs(Str, stdout);
673779