diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/ModuleUtils.cpp | 34 |
5 files changed, 56 insertions, 46 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index d3b8c4da5f4..28872566863 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2794,8 +2794,14 @@ Error BitcodeReader::globalCleanup() { } // Look for global variables which need to be renamed. + std::vector<std::pair<GlobalVariable *, GlobalVariable *>> UpgradedVariables; for (GlobalVariable &GV : TheModule->globals()) - UpgradeGlobalVariable(&GV); + if (GlobalVariable *Upgraded = UpgradeGlobalVariable(&GV)) + UpgradedVariables.emplace_back(&GV, Upgraded); + for (auto &Pair : UpgradedVariables) { + Pair.first->eraseFromParent(); + TheModule->getGlobalList().push_back(Pair.second); + } // Force deallocation of memory for these vectors to favor the client that // want lazy deserialization. diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index be874aca6d4..3d2e5e5ea00 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1966,7 +1966,7 @@ struct Structor { /// priority. void AsmPrinter::EmitXXStructorList(const DataLayout &DL, const Constant *List, bool isCtor) { - // Should be an array of '{ int, void ()* }' structs. The first value is the + // Should be an array of '{ i32, void ()*, i8* }' structs. The first value is the // init priority. if (!isa<ConstantArray>(List)) return; @@ -1974,12 +1974,10 @@ void AsmPrinter::EmitXXStructorList(const DataLayout &DL, const Constant *List, const ConstantArray *InitList = dyn_cast<ConstantArray>(List); if (!InitList) return; // Not an array! StructType *ETy = dyn_cast<StructType>(InitList->getType()->getElementType()); - // FIXME: Only allow the 3-field form in LLVM 4.0. - if (!ETy || ETy->getNumElements() < 2 || ETy->getNumElements() > 3) - return; // Not an array of two or three elements! - if (!isa<IntegerType>(ETy->getTypeAtIndex(0U)) || - !isa<PointerType>(ETy->getTypeAtIndex(1U))) return; // Not (int, ptr). - if (ETy->getNumElements() == 3 && !isa<PointerType>(ETy->getTypeAtIndex(2U))) + if (!ETy || ETy->getNumElements() != 3 || + !isa<IntegerType>(ETy->getTypeAtIndex(0U)) || + !isa<PointerType>(ETy->getTypeAtIndex(1U)) || + !isa<PointerType>(ETy->getTypeAtIndex(2U))) return; // Not (int, ptr, ptr). // Gather the structors in a form that's convenient for sorting by priority. @@ -1995,7 +1993,7 @@ void AsmPrinter::EmitXXStructorList(const DataLayout &DL, const Constant *List, Structor &S = Structors.back(); S.Priority = Priority->getLimitedValue(65535); S.Func = CS->getOperand(1); - if (ETy->getNumElements() == 3 && !CS->getOperand(2)->isNullValue()) + if (!CS->getOperand(2)->isNullValue()) S.ComdatKey = dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts()); } diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index c0fd3cd7cbd..e6a096a8855 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -805,9 +805,35 @@ bool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { return Upgraded; } -bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) { - // Nothing to do yet. - return false; +GlobalVariable *llvm::UpgradeGlobalVariable(GlobalVariable *GV) { + if (!(GV->hasName() && (GV->getName() == "llvm.global_ctors" || + GV->getName() == "llvm.global_dtors")) || + !GV->hasInitializer()) + return nullptr; + ArrayType *ATy = dyn_cast<ArrayType>(GV->getValueType()); + if (!ATy) + return nullptr; + StructType *STy = dyn_cast<StructType>(ATy->getElementType()); + if (!STy || STy->getNumElements() != 2) + return nullptr; + + LLVMContext &C = GV->getContext(); + IRBuilder<> IRB(C); + auto EltTy = StructType::get(STy->getElementType(0), STy->getElementType(1), + IRB.getInt8PtrTy()); + Constant *Init = GV->getInitializer(); + unsigned N = Init->getNumOperands(); + std::vector<Constant *> NewCtors(N); + for (unsigned i = 0; i != N; ++i) { + auto Ctor = cast<Constant>(Init->getOperand(i)); + NewCtors[i] = ConstantStruct::get( + EltTy, Ctor->getAggregateElement(0u), Ctor->getAggregateElement(1), + Constant::getNullValue(IRB.getInt8PtrTy())); + } + Constant *NewInit = ConstantArray::get(ArrayType::get(EltTy, N), NewCtors); + + return new GlobalVariable(NewInit->getType(), false, GV->getLinkage(), + NewInit, GV->getName()); } // Handles upgrading SSE2/AVX2/AVX512BW PSLLDQ intrinsics by converting them diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 1ba64f33380..f7004cf4eae 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -641,18 +641,18 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { PointerType *FuncPtrTy = FunctionType::get(Type::getVoidTy(Context), false)-> getPointerTo(DL.getProgramAddressSpace()); - // FIXME: Reject the 2-field form in LLVM 4.0. Assert(STy && (STy->getNumElements() == 2 || STy->getNumElements() == 3) && STy->getTypeAtIndex(0u)->isIntegerTy(32) && STy->getTypeAtIndex(1) == FuncPtrTy, "wrong type for intrinsic global variable", &GV); - if (STy->getNumElements() == 3) { - Type *ETy = STy->getTypeAtIndex(2); - Assert(ETy->isPointerTy() && - cast<PointerType>(ETy)->getElementType()->isIntegerTy(8), - "wrong type for intrinsic global variable", &GV); - } + Assert(STy->getNumElements() == 3, + "the third field of the element type is mandatory, " + "specify i8* null to migrate from the obsoleted 2-field form"); + Type *ETy = STy->getTypeAtIndex(2); + Assert(ETy->isPointerTy() && + cast<PointerType>(ETy)->getElementType()->isIntegerTy(8), + "wrong type for intrinsic global variable", &GV); } } diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp index b076e7503c6..c84beceee19 100644 --- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -27,44 +27,24 @@ static void appendToGlobalArray(const char *Array, Module &M, Function *F, // Get the current set of static global constructors and add the new ctor // to the list. SmallVector<Constant *, 16> CurrentCtors; - StructType *EltTy; + StructType *EltTy = StructType::get( + IRB.getInt32Ty(), PointerType::getUnqual(FnTy), IRB.getInt8PtrTy()); if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) { - ArrayType *ATy = cast<ArrayType>(GVCtor->getValueType()); - StructType *OldEltTy = cast<StructType>(ATy->getElementType()); - // Upgrade a 2-field global array type to the new 3-field format if needed. - if (Data && OldEltTy->getNumElements() < 3) - EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy), - IRB.getInt8PtrTy()); - else - EltTy = OldEltTy; if (Constant *Init = GVCtor->getInitializer()) { unsigned n = Init->getNumOperands(); CurrentCtors.reserve(n + 1); - for (unsigned i = 0; i != n; ++i) { - auto Ctor = cast<Constant>(Init->getOperand(i)); - if (EltTy != OldEltTy) - Ctor = - ConstantStruct::get(EltTy, Ctor->getAggregateElement((unsigned)0), - Ctor->getAggregateElement(1), - Constant::getNullValue(IRB.getInt8PtrTy())); - CurrentCtors.push_back(Ctor); - } + for (unsigned i = 0; i != n; ++i) + CurrentCtors.push_back(cast<Constant>(Init->getOperand(i))); } GVCtor->eraseFromParent(); - } else { - // Use the new three-field struct if there isn't one already. - EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy), - IRB.getInt8PtrTy()); } - // Build a 2 or 3 field global_ctor entry. We don't take a comdat key. + // Build a 3 field global_ctor entry. We don't take a comdat key. Constant *CSVals[3]; CSVals[0] = IRB.getInt32(Priority); CSVals[1] = F; - // FIXME: Drop support for the two element form in LLVM 4.0. - if (EltTy->getNumElements() >= 3) - CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy()) - : Constant::getNullValue(IRB.getInt8PtrTy()); + CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy()) + : Constant::getNullValue(IRB.getInt8PtrTy()); Constant *RuntimeCtorInit = ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements())); |