Do not optimize for host CPU by default.

GitHub: Fixes #323.
This commit is contained in:
David Nadlinger
2013-05-09 17:24:29 +02:00
parent 56e35e31a0
commit 30bf4e121f
3 changed files with 80 additions and 8 deletions

View File

@@ -23,7 +23,6 @@
#include "gen/irstate.h" #include "gen/irstate.h"
#include "gen/linkage.h" #include "gen/linkage.h"
#include "gen/llvm.h" #include "gen/llvm.h"
#include "gen/llvmcompat.h"
#include "gen/logger.h" #include "gen/logger.h"
#include "gen/metadata.h" #include "gen/metadata.h"
#include "gen/optimizer.h" #include "gen/optimizer.h"

View File

@@ -6,8 +6,15 @@
// file for details. // file for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//
// Note: The target CPU detection logic has been adapted from Clang
// (lib/Driver/Tools.cpp).
//
//===----------------------------------------------------------------------===//
#include "driver/target.h" #include "driver/target.h"
#include "gen/llvmcompat.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/Host.h" #include "llvm/Support/Host.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
@@ -16,6 +23,57 @@
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
#include "mars.h" #include "mars.h"
static std::string getX86TargetCPU(std::string arch,
const llvm::Triple &triple)
{
if (!arch.empty()) {
if (arch != "native")
return arch;
// FIXME: Reject attempts to use -march=native unless the target matches
// the host.
//
// FIXME: We should also incorporate the detected target features for use
// with -native.
std::string cpu = llvm::sys::getHostCPUName();
if (!cpu.empty() && cpu != "generic")
return cpu;
}
// Select the default CPU if none was given (or detection failed).
bool is64Bit = triple.getArch() == llvm::Triple::x86_64;
if (triple.isOSDarwin())
return is64Bit ? "core2" : "yonah";
// Everything else goes to x86-64 in 64-bit mode.
if (is64Bit)
return "x86-64";
if (triple.getOSName().startswith("haiku"))
return "i586";
if (triple.getOSName().startswith("openbsd"))
return "i486";
if (triple.getOSName().startswith("bitrig"))
return "i686";
if (triple.getOSName().startswith("freebsd"))
return "i486";
if (triple.getOSName().startswith("netbsd"))
return "i486";
#if LDC_LLVM_VER >= 302
// All x86 devices running Android have core2 as their common
// denominator. This makes a better choice than pentium4.
if (triple.getEnvironment() == llvm::Triple::Android)
return "core2";
#endif
// Fallback to p4.
return "pentium4";
}
llvm::TargetMachine* createTargetMachine( llvm::TargetMachine* createTargetMachine(
std::string targetTriple, std::string targetTriple,
std::string arch, std::string arch,
@@ -46,7 +104,7 @@ llvm::TargetMachine* createTargetMachine(
#endif #endif
} }
std::string triple; llvm::Triple triple;
// did the user override the target triple? // did the user override the target triple?
if (targetTriple.empty()) if (targetTriple.empty())
@@ -56,21 +114,20 @@ llvm::TargetMachine* createTargetMachine(
error("you must specify a target triple as well with -mtriple when using the -arch option"); error("you must specify a target triple as well with -mtriple when using the -arch option");
fatal(); fatal();
} }
triple = defaultTriple; triple = llvm::Triple(defaultTriple);
} }
else else
{ {
triple = llvm::Triple::normalize(targetTriple); triple = llvm::Triple(llvm::Triple::normalize(targetTriple));
} }
// Allocate target machine. // Allocate target machine.
const llvm::Target *theTarget = NULL; const llvm::Target *theTarget = NULL;
// Check whether the user has explicitly specified an architecture to compile for. // Check whether the user has explicitly specified an architecture to compile for.
if (arch.empty()) if (arch.empty())
{ {
std::string Err; std::string Err;
theTarget = llvm::TargetRegistry::lookupTarget(triple, Err); theTarget = llvm::TargetRegistry::lookupTarget(triple.str(), Err);
if (theTarget == 0) if (theTarget == 0)
{ {
error("%s Please use the -march option.", Err.c_str()); error("%s Please use the -march option.", Err.c_str());
@@ -96,6 +153,19 @@ llvm::TargetMachine* createTargetMachine(
} }
} }
// With an empty CPU string, LLVM will default to the host CPU, which is
// usually not what we want (expected behavior from other compilers is
// to default to "generic").
if (cpu.empty())
{
if (triple.getArch() == llvm::Triple::x86_64 ||
triple.getArch() == llvm::Triple::x86)
{
cpu = getX86TargetCPU(arch, triple);
}
}
// Package up features to be passed to target/subtarget // Package up features to be passed to target/subtarget
std::string FeaturesStr; std::string FeaturesStr;
if (cpu.size() || attrs.size()) if (cpu.size() || attrs.size())
@@ -109,14 +179,14 @@ llvm::TargetMachine* createTargetMachine(
#if LDC_LLVM_VER == 300 #if LDC_LLVM_VER == 300
llvm::NoFramePointerElim = genDebugInfo; llvm::NoFramePointerElim = genDebugInfo;
return theTarget->createTargetMachine(triple, cpu, FeaturesStr, return theTarget->createTargetMachine(triple.str(), cpu, FeaturesStr,
relocModel, codeModel); relocModel, codeModel);
#else #else
llvm::TargetOptions targetOptions; llvm::TargetOptions targetOptions;
targetOptions.NoFramePointerElim = genDebugInfo; targetOptions.NoFramePointerElim = genDebugInfo;
return theTarget->createTargetMachine( return theTarget->createTargetMachine(
triple, triple.str(),
cpu, cpu,
FeaturesStr, FeaturesStr,
targetOptions, targetOptions,

View File

@@ -16,6 +16,9 @@
#define LDC_DRIVER_TARGET_H #define LDC_DRIVER_TARGET_H
#include "llvm/Support/CodeGen.h" #include "llvm/Support/CodeGen.h"
#if LDC_LLVM_VER == 300
#include "llvm/Target/TargetMachine.h" // For llvm::CodeGenOpt::Level.
#endif
#include <string> #include <string>
#include <vector> #include <vector>