@@ -946,14 +946,16 @@ bool eraseDummyAfterReturnBB(llvm::BasicBlock *bb) {
946
946
947
947
/* *
948
948
* LLVM doesn't really support weak linkage for MSVC targets, it just prevents
949
- * inlining. We can emulate it though, by conceptually renaming the defined
950
- * function, only declaring the original function and embedding a linker
951
- * directive in the object file, instructing the linker to fall back to the weak
952
- * implementation if there's no strong definition.
949
+ * inlining. We can emulate it though, by renaming the defined function, only
950
+ * declaring the original function and embedding a linker directive in the
951
+ * object file, instructing the linker to fall back to the weak implementation
952
+ * if there's no strong definition.
953
953
* The object file still needs to be pulled in by the linker for the directive
954
954
* to be found.
955
955
*/
956
- void emulateWeakAnyLinkageForMSVC (LLFunction *func, LINK linkage) {
956
+ void emulateWeakAnyLinkageForMSVC (IrFunction *irFunc, LINK linkage) {
957
+ LLFunction *func = irFunc->getLLVMFunc ();
958
+
957
959
const bool isWin32 = global.params .targetTriple ->isArch32Bit ();
958
960
959
961
std::string mangleBuffer;
@@ -987,17 +989,22 @@ void emulateWeakAnyLinkageForMSVC(LLFunction *func, LINK linkage) {
987
989
(" /ALTERNATENAME:" + finalMangle + " =" + finalWeakMangle).str ();
988
990
gIR ->addLinkerOption (llvm::StringRef (linkerOption));
989
991
990
- // work around LLVM assertion when cloning a function's debuginfos
991
- func->setSubprogram (nullptr );
992
+ // rename existing function
993
+ const std::string oldName = func->getName ().str ();
994
+ func->setName (" \1 " + finalWeakMangle);
995
+ if (func->hasComdat ()) {
996
+ func->setComdat (gIR ->module .getOrInsertComdat (func->getName ()));
997
+ }
992
998
993
- llvm::ValueToValueMapTy dummy;
994
- auto clone = llvm::CloneFunction (func, dummy);
995
- clone-> setName ( " \1 " + finalWeakMangle);
996
- setLinkage ({ LLGlobalValue::ExternalLinkage, func-> hasComdat ()}, clone );
999
+ // create a new body-less declaration with the old name
1000
+ auto newFunc =
1001
+ LLFunction::Create (func-> getFunctionType (),
1002
+ LLGlobalValue::ExternalLinkage, oldName, & gIR -> module );
997
1003
998
- // reduce the original definition to a declaration
999
- setLinkage ({LLGlobalValue::ExternalLinkage, false }, func);
1000
- func->deleteBody ();
1004
+ // replace existing and future uses of the old, renamed function with the new
1005
+ // declaration
1006
+ irFunc->setLLVMFunc (newFunc);
1007
+ func->replaceNonMetadataUsesWith (newFunc);
1001
1008
}
1002
1009
1003
1010
} // anonymous namespace
@@ -1317,8 +1324,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
1317
1324
1318
1325
// Push cleanup block that calls va_end to match the va_start call.
1319
1326
{
1320
- auto *vaendBB =
1321
- llvm::BasicBlock::Create (gIR ->context (), " vaend" , gIR ->topfunc ());
1327
+ auto *vaendBB = llvm::BasicBlock::Create (gIR ->context (), " vaend" , func);
1322
1328
const auto savedInsertPoint = gIR ->saveInsertPoint ();
1323
1329
gIR ->ir ->SetInsertPoint (vaendBB);
1324
1330
gIR ->ir ->CreateCall (GET_INTRINSIC_DECL (vaend), llAp);
@@ -1379,7 +1385,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
1379
1385
if (func->getLinkage () == LLGlobalValue::WeakAnyLinkage &&
1380
1386
!func->hasDLLExportStorageClass () &&
1381
1387
global.params .targetTriple ->isWindowsMSVCEnvironment ()) {
1382
- emulateWeakAnyLinkageForMSVC (func , fd->linkage );
1388
+ emulateWeakAnyLinkageForMSVC (irFunc , fd->linkage );
1383
1389
}
1384
1390
}
1385
1391
0 commit comments