llvm.org GIT mirror llvm / 35ecd26
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254907 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
2 changed file(s) with 42 addition(s) and 92 deletion(s). Raw diff Collapse all Expand all
508508
509509 void computeTypeMapping();
510510
511 void upgradeMismatchedGlobalArray(StringRef Name);
512 void upgradeMismatchedGlobals();
513
514511 bool linkIfNeeded(GlobalValue &GV);
515512 Constant *linkAppendingVarProto(GlobalVariable *DstGV,
516513 const GlobalVariable *SrcGV);
11891186 TypeMap.linkDefinedTypeBodies();
11901187 }
11911188
1192 static void upgradeGlobalArray(GlobalVariable *GV) {
1193 ArrayType *ATy = cast(GV->getType()->getElementType());
1194 StructType *OldTy = cast(ATy->getElementType());
1195 assert(OldTy->getNumElements() == 2 && "Expected to upgrade from 2 elements");
1196
1197 // Get the upgraded 3 element type.
1198 PointerType *VoidPtrTy = Type::getInt8Ty(GV->getContext())->getPointerTo();
1199 Type *Tys[3] = {OldTy->getElementType(0), OldTy->getElementType(1),
1200 VoidPtrTy};
1201 StructType *NewTy = StructType::get(GV->getContext(), Tys, false);
1202
1203 // Build new constants with a null third field filled in.
1204 Constant *OldInitC = GV->getInitializer();
1205 ConstantArray *OldInit = dyn_cast(OldInitC);
1206 if (!OldInit && !isa(OldInitC))
1207 // Invalid initializer; give up.
1208 return;
1209 std::vector Initializers;
1210 if (OldInit && OldInit->getNumOperands()) {
1211 Value *Null = Constant::getNullValue(VoidPtrTy);
1212 for (Use &U : OldInit->operands()) {
1213 ConstantStruct *Init = cast(U.get());
1214 Initializers.push_back(ConstantStruct::get(
1215 NewTy, Init->getOperand(0), Init->getOperand(1), Null, nullptr));
1216 }
1217 }
1218 assert(Initializers.size() == ATy->getNumElements() &&
1219 "Failed to copy all array elements");
1220
1221 // Replace the old GV with a new one.
1222 ATy = ArrayType::get(NewTy, Initializers.size());
1223 Constant *NewInit = ConstantArray::get(ATy, Initializers);
1224 GlobalVariable *NewGV = new GlobalVariable(
1225 *GV->getParent(), ATy, GV->isConstant(), GV->getLinkage(), NewInit, "",
1226 GV, GV->getThreadLocalMode(), GV->getType()->getAddressSpace(),
1227 GV->isExternallyInitialized());
1228 NewGV->copyAttributesFrom(GV);
1229 NewGV->takeName(GV);
1230 assert(GV->use_empty() && "program cannot use initializer list");
1231 GV->eraseFromParent();
1232 }
1233
1234 void ModuleLinker::upgradeMismatchedGlobalArray(StringRef Name) {
1235 // Look for the global arrays.
1236 auto *DstGV = dyn_cast_or_null(DstM.getNamedValue(Name));
1237 if (!DstGV)
1238 return;
1239 auto *SrcGV = dyn_cast_or_null(SrcM.getNamedValue(Name));
1240 if (!SrcGV)
1241 return;
1242
1243 // Check if the types already match.
1244 auto *DstTy = cast(DstGV->getType()->getElementType());
1245 auto *SrcTy =
1246 cast(TypeMap.get(SrcGV->getType()->getElementType()));
1247 if (DstTy == SrcTy)
1248 return;
1249
1250 // Grab the element types. We can only upgrade an array of a two-field
1251 // struct. Only bother if the other one has three-fields.
1252 auto *DstEltTy = cast(DstTy->getElementType());
1253 auto *SrcEltTy = cast(SrcTy->getElementType());
1254 if (DstEltTy->getNumElements() == 2 && SrcEltTy->getNumElements() == 3) {
1255 upgradeGlobalArray(DstGV);
1256 return;
1257 }
1258 if (DstEltTy->getNumElements() == 3 && SrcEltTy->getNumElements() == 2)
1259 upgradeGlobalArray(SrcGV);
1260
1261 // We can't upgrade any other differences.
1262 }
1263
1264 void ModuleLinker::upgradeMismatchedGlobals() {
1265 upgradeMismatchedGlobalArray("llvm.global_ctors");
1266 upgradeMismatchedGlobalArray("llvm.global_dtors");
1267 }
1268
12691189 static void getArrayElements(const Constant *C,
12701190 SmallVectorImpl &Dest) {
12711191 unsigned NumElements = cast(C->getType())->getNumElements();
12781198 /// Return true on error.
12791199 Constant *ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
12801200 const GlobalVariable *SrcGV) {
1281 ArrayType *SrcTy =
1282 cast(TypeMap.get(SrcGV->getType()->getElementType()));
1283 Type *EltTy = SrcTy->getElementType();
1201 Type *EltTy = cast(TypeMap.get(SrcGV->getType()->getElementType()))
1202 ->getElementType();
1203
1204 StringRef Name = SrcGV->getName();
1205 bool IsNewStructor = false;
1206 bool IsOldStructor = false;
1207 if (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") {
1208 if (cast(EltTy)->getNumElements() == 3)
1209 IsNewStructor = true;
1210 else
1211 IsOldStructor = true;
1212 }
1213
1214 PointerType *VoidPtrTy = Type::getInt8Ty(SrcGV->getContext())->getPointerTo();
1215 if (IsOldStructor) {
1216 auto &ST = *cast(EltTy);
1217 Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy};
1218 EltTy = StructType::get(SrcGV->getContext(), Tys, false);
1219 }
12841220
12851221 if (DstGV) {
12861222 ArrayType *DstTy = cast(DstGV->getType()->getElementType());
13341270 SmallVector SrcElements;
13351271 getArrayElements(SrcGV->getInitializer(), SrcElements);
13361272
1337 StringRef Name = SrcGV->getName();
1338 bool IsNewStructor =
1339 (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") &&
1340 cast(EltTy)->getNumElements() == 3;
13411273 if (IsNewStructor)
13421274 SrcElements.erase(
13431275 std::remove_if(SrcElements.begin(), SrcElements.end(),
13661298 ValueMap[SrcGV] = Ret;
13671299
13681300 for (auto *V : SrcElements) {
1369 DstElements.push_back(
1370 MapValue(V, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer));
1301 Constant *NewV;
1302 if (IsOldStructor) {
1303 auto *S = cast(V);
1304 auto *E1 = MapValue(S->getOperand(0), ValueMap, RF_MoveDistinctMDs,
1305 &TypeMap, &ValMaterializer);
1306 auto *E2 = MapValue(S->getOperand(1), ValueMap, RF_MoveDistinctMDs,
1307 &TypeMap, &ValMaterializer);
1308 Value *Null = Constant::getNullValue(VoidPtrTy);
1309 NewV =
1310 ConstantStruct::get(cast(EltTy), E1, E2, Null, nullptr);
1311 } else {
1312 NewV =
1313 MapValue(V, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer);
1314 }
1315 DstElements.push_back(NewV);
13711316 }
13721317
13731318 NG->setInitializer(ConstantArray::get(NewType, DstElements));
18761821 ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc);
18771822 }
18781823
1879 // Upgrade mismatched global arrays.
1880 upgradeMismatchedGlobals();
1881
18821824 for (GlobalVariable &GV : SrcM.globals())
18831825 if (const Comdat *SC = GV.getComdat())
18841826 ComdatMembers[SC].push_back(&GV);
0 ; RUN: llvm-link -S %s | FileCheck %s
1
2 @llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }]
3 ; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null }]
4
5 define void @f() {
6 ret void
7 }