forked from OSchip/llvm-project
[LinkModules] Change the way ModuleLinker merges triples.
This commit makes the following changes: - Stop issuing a warning when the triples' string representations do not match exactly if the Triple objects generated from the strings compare equal. - On Apple platforms, choose the triple that has the larger minimum version number. rdar://problem/16743513 Differential Revision: http://reviews.llvm.org/D7591 llvm-svn: 228999
This commit is contained in:
parent
dc3a8a4a66
commit
c43df5187c
|
@ -202,6 +202,13 @@ public:
|
|||
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
|
||||
const Twine &EnvironmentStr);
|
||||
|
||||
bool operator==(const Triple &Other) const {
|
||||
return Arch == Other.Arch && SubArch == Other.SubArch &&
|
||||
Vendor == Other.Vendor && OS == Other.OS &&
|
||||
Environment == Other.Environment &&
|
||||
ObjectFormat == Other.ObjectFormat;
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Normalization
|
||||
/// @{
|
||||
|
@ -339,6 +346,12 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool isOSVersionLT(const Triple &Other) const {
|
||||
unsigned RHS[3];
|
||||
Other.getOSVersion(RHS[0], RHS[1], RHS[2]);
|
||||
return isOSVersionLT(RHS[0], RHS[1], RHS[2]);
|
||||
}
|
||||
|
||||
/// isMacOSXVersionLT - Comparison function for checking OS X version
|
||||
/// compatibility, which handles supporting skewed version numbering schemes
|
||||
/// used by the "darwin" triples.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
|
@ -1457,6 +1458,28 @@ bool ModuleLinker::linkModuleFlagsMetadata() {
|
|||
return HasErr;
|
||||
}
|
||||
|
||||
// This function returns true if the triples match.
|
||||
static bool triplesMatch(const Triple &T0, const Triple &T1) {
|
||||
// If vendor is apple, ignore the version number.
|
||||
if (T0.getVendor() == Triple::Apple)
|
||||
return T0.getArch() == T1.getArch() &&
|
||||
T0.getSubArch() == T1.getSubArch() &&
|
||||
T0.getVendor() == T1.getVendor() &&
|
||||
T0.getOS() == T1.getOS();
|
||||
|
||||
return T0 == T1;
|
||||
}
|
||||
|
||||
// This function returns the merged triple.
|
||||
static std::string mergeTriples(const Triple &SrcTriple, const Triple &DstTriple) {
|
||||
// If vendor is apple, pick the triple with the larger version number.
|
||||
if (SrcTriple.getVendor() == Triple::Apple)
|
||||
if (DstTriple.isOSVersionLT(SrcTriple))
|
||||
return SrcTriple.str();
|
||||
|
||||
return DstTriple.str();
|
||||
}
|
||||
|
||||
bool ModuleLinker::run() {
|
||||
assert(DstM && "Null destination module");
|
||||
assert(SrcM && "Null source module");
|
||||
|
@ -1466,10 +1489,6 @@ bool ModuleLinker::run() {
|
|||
if (!DstM->getDataLayout() && SrcM->getDataLayout())
|
||||
DstM->setDataLayout(SrcM->getDataLayout());
|
||||
|
||||
// Copy the target triple from the source to dest if the dest's is empty.
|
||||
if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty())
|
||||
DstM->setTargetTriple(SrcM->getTargetTriple());
|
||||
|
||||
if (SrcM->getDataLayout() && DstM->getDataLayout() &&
|
||||
*SrcM->getDataLayout() != *DstM->getDataLayout()) {
|
||||
emitWarning("Linking two modules of different data layouts: '" +
|
||||
|
@ -1478,14 +1497,21 @@ bool ModuleLinker::run() {
|
|||
DstM->getModuleIdentifier() + "' is '" +
|
||||
DstM->getDataLayoutStr() + "'\n");
|
||||
}
|
||||
if (!SrcM->getTargetTriple().empty() &&
|
||||
DstM->getTargetTriple() != SrcM->getTargetTriple()) {
|
||||
|
||||
// Copy the target triple from the source to dest if the dest's is empty.
|
||||
if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty())
|
||||
DstM->setTargetTriple(SrcM->getTargetTriple());
|
||||
|
||||
Triple SrcTriple(SrcM->getTargetTriple()), DstTriple(DstM->getTargetTriple());
|
||||
|
||||
if (!SrcM->getTargetTriple().empty() && !triplesMatch(SrcTriple, DstTriple))
|
||||
emitWarning("Linking two modules of different target triples: " +
|
||||
SrcM->getModuleIdentifier() + "' is '" +
|
||||
SrcM->getTargetTriple() + "' whereas '" +
|
||||
DstM->getModuleIdentifier() + "' is '" +
|
||||
DstM->getTargetTriple() + "'\n");
|
||||
}
|
||||
|
||||
DstM->setTargetTriple(mergeTriples(SrcTriple, DstTriple));
|
||||
|
||||
// Append the module inline asm string.
|
||||
if (!SrcM->getModuleInlineAsm().empty()) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
target triple = "x86_64-apple-macosx10.10.0"
|
|
@ -0,0 +1 @@
|
|||
target triple = "x86_64-apple-macosx10.8.0"
|
|
@ -0,0 +1 @@
|
|||
target triple = "i386-apple-macosx10.9.0"
|
|
@ -0,0 +1 @@
|
|||
target triple = "x86_64h-apple-macosx10.9.0"
|
|
@ -1 +1 @@
|
|||
target triple = "e"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
|
|
@ -1 +1 @@
|
|||
target triple = "E"
|
||||
target triple = "i386-unknown-linux-gnu"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
target triple = "x86_64h-unknown-linux-gnu"
|
|
@ -0,0 +1,24 @@
|
|||
; RUN: llvm-link %s %S/Inputs/apple-version/1.ll -S -o - 2>%t.err | FileCheck %s -check-prefix=CHECK1
|
||||
; RUN: cat %t.err | FileCheck --check-prefix=WARN1 --allow-empty %s
|
||||
; RUN: llvm-link %s %S/Inputs/apple-version/2.ll -S -o - 2>%t.err | FileCheck %s -check-prefix=CHECK2
|
||||
; RUN: cat %t.err | FileCheck --check-prefix=WARN2 --allow-empty %s
|
||||
; RUN: llvm-link %s %S/Inputs/apple-version/3.ll -S -o /dev/null 2>%t.err
|
||||
; RUN: cat %t.err | FileCheck --check-prefix=WARN3 %s
|
||||
; RUN: llvm-link %s %S/Inputs/apple-version/4.ll -S -o /dev/null 2>%t.err
|
||||
; RUN: cat %t.err | FileCheck --check-prefix=WARN4 --allow-empty %s
|
||||
|
||||
; Check that the triple that has the larger version number is chosen and no
|
||||
; warnings are issued when the Triples differ only in version numbers.
|
||||
|
||||
; CHECK1: target triple = "x86_64-apple-macosx10.10.0"
|
||||
; WARN1-NOT: WARNING
|
||||
; CHECK2: target triple = "x86_64-apple-macosx10.9.0"
|
||||
; WARN2-NOT: WARNING
|
||||
|
||||
; i386 and x86_64 map to different ArchType enums.
|
||||
; WARN3: WARNING: Linking two modules of different target triples
|
||||
|
||||
; x86_64h and x86_64 map to the same ArchType enum.
|
||||
; WARN4-NOT: WARNING
|
||||
|
||||
target triple = "x86_64-apple-macosx10.9.0"
|
|
@ -8,10 +8,14 @@
|
|||
; RUN: llvm-link -suppress-warnings %s %S/Inputs/targettriple-b.ll -S -o - 2>%t.no-warn.err | FileCheck %s
|
||||
; RUN: (echo foo ;cat %t.no-warn.err) | FileCheck --check-prefix=WARN-A %s
|
||||
|
||||
target triple = "e"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; CHECK: target triple = "e"
|
||||
; CHECK: target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; WARN-A-NOT: WARNING
|
||||
|
||||
; i386 and x86_64 map to different ArchType enums.
|
||||
; WARN-B: WARNING: Linking two modules of different target triples:
|
||||
|
||||
; x86_64h and x86_64 map to the same ArchType enum.
|
||||
; WARN-C-NOT: WARNING
|
||||
|
|
Loading…
Reference in New Issue