diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -1443,6 +1443,8 @@ computeTypeMapping(); std::reverse(Worklist.begin(), Worklist.end()); + SmallVector, 16> MappedConstants; + while (!Worklist.empty()) { GlobalValue *GV = Worklist.back(); Worklist.pop_back(); @@ -1453,12 +1455,70 @@ continue; assert(!GV->isDeclaration()); - Mapper.mapValue(*GV); + + // Set the initializer of global variable to be empty so that + // the global varaibles in the initializer won't be generated. + Constant *InitCnst = nullptr; + StringRef Name = GV->getName(); + if (Name != "llvm.global_ctors" && Name != "llvm.global_dtors") { + if (auto *V = dyn_cast(GV)) { + if (V->hasInitializer()) { + InitCnst = V->getInitializer(); + if (InitCnst != Constant::getNullValue(V->getValueType())) + V->setInitializer(Constant::getNullValue(V->getValueType())); + else + InitCnst = nullptr; + } + } + } + + // Record the mapping between the old initializer and new + // global variable. + auto NewV = Mapper.mapValue(*GV); + if (InitCnst) { + assert(NewV); + NewV = NewV->stripPointerCastsAndAliases(); + auto *NewGV = dyn_cast(NewV); + assert(NewGV); + MappedConstants.push_back({InitCnst, NewGV}); + } + if (FoundError) return std::move(*FoundError); flushRAUWWorklist(); } + // Generate the new iniitializer based on the + // mapping btween the old initializer and the + // new global variable. By this way, the original + // lexical order can be preserved. + for (auto &MC : MappedConstants) { + auto OldCnst = dyn_cast(MC.first); + auto NewCnst = Mapper.mapValue(*OldCnst); + Constant *C = dyn_cast(NewCnst); + assert(C); + if (MC.second->getInitializer() != + Constant::getNullValue(MC.second->getValueType())) { + SmallVector NewElements; + getArrayElements(MC.second->getInitializer(), NewElements); + + SmallVector OldElements; + getArrayElements(C, OldElements); + + unsigned Size = OldElements.size(); + while (Size > 0) { + NewElements.pop_back(); + Size--; + } + NewElements.append(OldElements.begin(), OldElements.end()); + ArrayType *ATyp = + dyn_cast(MC.second->getType()->getElementType()); + assert(ATyp); + C = ConstantArray::get(ATyp, NewElements); + } + MC.second->setInitializer(C); + } + // Note that we are done linking global value bodies. This prevents // metadata linking from creating new references. DoneLinkingBodies = true;