[llvm] r254907 - Change how the linker handles the old llvm.global_ctors.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 7 05:24:24 PST 2015
Author: rafael
Date: Mon Dec 7 07:24:23 2015
New Revision: 254907
URL: http://llvm.org/viewvc/llvm-project?rev=254907&view=rev
Log:
Change how the linker handles the old llvm.global_ctors.
Now instead of changing it to the new format and then linking, it just
handles the old format while copying it over.
The main differences are:
* There is no rauw in the source module.
* An old format input is always upgraded.
The first item helps with having a sane API that passes in a GV list to
the linker.
The second one is a small step in deprecating the old format.
Added:
llvm/trunk/test/Linker/ctors5.ll
Modified:
llvm/trunk/lib/Linker/LinkModules.cpp
Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=254907&r1=254906&r2=254907&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Mon Dec 7 07:24:23 2015
@@ -509,9 +509,6 @@ private:
void computeTypeMapping();
- void upgradeMismatchedGlobalArray(StringRef Name);
- void upgradeMismatchedGlobals();
-
bool linkIfNeeded(GlobalValue &GV);
Constant *linkAppendingVarProto(GlobalVariable *DstGV,
const GlobalVariable *SrcGV);
@@ -1190,83 +1187,6 @@ void ModuleLinker::computeTypeMapping()
TypeMap.linkDefinedTypeBodies();
}
-static void upgradeGlobalArray(GlobalVariable *GV) {
- ArrayType *ATy = cast<ArrayType>(GV->getType()->getElementType());
- StructType *OldTy = cast<StructType>(ATy->getElementType());
- assert(OldTy->getNumElements() == 2 && "Expected to upgrade from 2 elements");
-
- // Get the upgraded 3 element type.
- PointerType *VoidPtrTy = Type::getInt8Ty(GV->getContext())->getPointerTo();
- Type *Tys[3] = {OldTy->getElementType(0), OldTy->getElementType(1),
- VoidPtrTy};
- StructType *NewTy = StructType::get(GV->getContext(), Tys, false);
-
- // Build new constants with a null third field filled in.
- Constant *OldInitC = GV->getInitializer();
- ConstantArray *OldInit = dyn_cast<ConstantArray>(OldInitC);
- if (!OldInit && !isa<ConstantAggregateZero>(OldInitC))
- // Invalid initializer; give up.
- return;
- std::vector<Constant *> Initializers;
- if (OldInit && OldInit->getNumOperands()) {
- Value *Null = Constant::getNullValue(VoidPtrTy);
- for (Use &U : OldInit->operands()) {
- ConstantStruct *Init = cast<ConstantStruct>(U.get());
- Initializers.push_back(ConstantStruct::get(
- NewTy, Init->getOperand(0), Init->getOperand(1), Null, nullptr));
- }
- }
- assert(Initializers.size() == ATy->getNumElements() &&
- "Failed to copy all array elements");
-
- // Replace the old GV with a new one.
- ATy = ArrayType::get(NewTy, Initializers.size());
- Constant *NewInit = ConstantArray::get(ATy, Initializers);
- GlobalVariable *NewGV = new GlobalVariable(
- *GV->getParent(), ATy, GV->isConstant(), GV->getLinkage(), NewInit, "",
- GV, GV->getThreadLocalMode(), GV->getType()->getAddressSpace(),
- GV->isExternallyInitialized());
- NewGV->copyAttributesFrom(GV);
- NewGV->takeName(GV);
- assert(GV->use_empty() && "program cannot use initializer list");
- GV->eraseFromParent();
-}
-
-void ModuleLinker::upgradeMismatchedGlobalArray(StringRef Name) {
- // Look for the global arrays.
- auto *DstGV = dyn_cast_or_null<GlobalVariable>(DstM.getNamedValue(Name));
- if (!DstGV)
- return;
- auto *SrcGV = dyn_cast_or_null<GlobalVariable>(SrcM.getNamedValue(Name));
- if (!SrcGV)
- return;
-
- // Check if the types already match.
- auto *DstTy = cast<ArrayType>(DstGV->getType()->getElementType());
- auto *SrcTy =
- cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType()));
- if (DstTy == SrcTy)
- return;
-
- // Grab the element types. We can only upgrade an array of a two-field
- // struct. Only bother if the other one has three-fields.
- auto *DstEltTy = cast<StructType>(DstTy->getElementType());
- auto *SrcEltTy = cast<StructType>(SrcTy->getElementType());
- if (DstEltTy->getNumElements() == 2 && SrcEltTy->getNumElements() == 3) {
- upgradeGlobalArray(DstGV);
- return;
- }
- if (DstEltTy->getNumElements() == 3 && SrcEltTy->getNumElements() == 2)
- upgradeGlobalArray(SrcGV);
-
- // We can't upgrade any other differences.
-}
-
-void ModuleLinker::upgradeMismatchedGlobals() {
- upgradeMismatchedGlobalArray("llvm.global_ctors");
- upgradeMismatchedGlobalArray("llvm.global_dtors");
-}
-
static void getArrayElements(const Constant *C,
SmallVectorImpl<Constant *> &Dest) {
unsigned NumElements = cast<ArrayType>(C->getType())->getNumElements();
@@ -1279,9 +1199,25 @@ static void getArrayElements(const Const
/// Return true on error.
Constant *ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
const GlobalVariable *SrcGV) {
- ArrayType *SrcTy =
- cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType()));
- Type *EltTy = SrcTy->getElementType();
+ Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType()))
+ ->getElementType();
+
+ StringRef Name = SrcGV->getName();
+ bool IsNewStructor = false;
+ bool IsOldStructor = false;
+ if (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") {
+ if (cast<StructType>(EltTy)->getNumElements() == 3)
+ IsNewStructor = true;
+ else
+ IsOldStructor = true;
+ }
+
+ PointerType *VoidPtrTy = Type::getInt8Ty(SrcGV->getContext())->getPointerTo();
+ if (IsOldStructor) {
+ auto &ST = *cast<StructType>(EltTy);
+ Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy};
+ EltTy = StructType::get(SrcGV->getContext(), Tys, false);
+ }
if (DstGV) {
ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType());
@@ -1335,10 +1271,6 @@ Constant *ModuleLinker::linkAppendingVar
SmallVector<Constant *, 16> SrcElements;
getArrayElements(SrcGV->getInitializer(), SrcElements);
- StringRef Name = SrcGV->getName();
- bool IsNewStructor =
- (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") &&
- cast<StructType>(EltTy)->getNumElements() == 3;
if (IsNewStructor)
SrcElements.erase(
std::remove_if(SrcElements.begin(), SrcElements.end(),
@@ -1367,8 +1299,21 @@ Constant *ModuleLinker::linkAppendingVar
ValueMap[SrcGV] = Ret;
for (auto *V : SrcElements) {
- DstElements.push_back(
- MapValue(V, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer));
+ Constant *NewV;
+ if (IsOldStructor) {
+ auto *S = cast<ConstantStruct>(V);
+ auto *E1 = MapValue(S->getOperand(0), ValueMap, RF_MoveDistinctMDs,
+ &TypeMap, &ValMaterializer);
+ auto *E2 = MapValue(S->getOperand(1), ValueMap, RF_MoveDistinctMDs,
+ &TypeMap, &ValMaterializer);
+ Value *Null = Constant::getNullValue(VoidPtrTy);
+ NewV =
+ ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null, nullptr);
+ } else {
+ NewV =
+ MapValue(V, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer);
+ }
+ DstElements.push_back(NewV);
}
NG->setInitializer(ConstantArray::get(NewType, DstElements));
@@ -1877,9 +1822,6 @@ bool ModuleLinker::run() {
ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc);
}
- // Upgrade mismatched global arrays.
- upgradeMismatchedGlobals();
-
for (GlobalVariable &GV : SrcM.globals())
if (const Comdat *SC = GV.getComdat())
ComdatMembers[SC].push_back(&GV);
Added: llvm/trunk/test/Linker/ctors5.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/ctors5.ll?rev=254907&view=auto
==============================================================================
--- llvm/trunk/test/Linker/ctors5.ll (added)
+++ llvm/trunk/test/Linker/ctors5.ll Mon Dec 7 07:24:23 2015
@@ -0,0 +1,8 @@
+; RUN: llvm-link -S %s | FileCheck %s
+
+ at llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }]
+; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null }]
+
+define void @f() {
+ ret void
+}
More information about the llvm-commits
mailing list