Merge remote-tracking branch 'origin/ltsmaster'

This commit is contained in:
Kai Nacke 2016-03-13 16:44:07 +01:00
commit 6e0badadf1
9 changed files with 97 additions and 54 deletions

View file

@ -17,7 +17,7 @@ include(CheckCXXCompilerFlag)
#
find_package(LLVM 3.5 REQUIRED
all-targets analysis asmparser asmprinter bitreader bitwriter codegen core debuginfocodeview debuginfodwarf debuginfopdb instcombine ipa ipo instrumentation irreader linker lto mc mcdisassembler mcparser objcarcopts object option profiledata scalaropts selectiondag support tablegen target transformutils vectorize ${EXTRA_LLVM_MODULES})
all-targets analysis asmparser asmprinter bitreader bitwriter codegen core debuginfocodeview debuginfodwarf debuginfopdb globalisel instcombine ipa ipo instrumentation irreader linker lto mc mcdisassembler mcparser objcarcopts object option profiledata scalaropts selectiondag support tablegen target transformutils vectorize ${EXTRA_LLVM_MODULES})
math(EXPR LDC_LLVM_VER ${LLVM_VERSION_MAJOR}*100+${LLVM_VERSION_MINOR})
# Remove LLVMTableGen library from list of libraries
string(REGEX MATCH "^-.*LLVMTableGen[^;]*;|;-.*LLVMTableGen[^;]*" LLVM_TABLEGEN_LIBRARY "${LLVM_LIBRARIES}")

View file

@ -76,8 +76,9 @@ if ((WIN32 AND NOT(MINGW OR CYGWIN)) OR NOT LLVM_CONFIG)
list(APPEND LLVM_FIND_COMPONENTS "debuginfo")
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-8][\\.0-9A-Za-z]*")
# Versions below 3.9 do not support components debuginfocodeview
# Versions below 3.9 do not support components debuginfocodeview, globalisel
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfocodeview" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "globalisel" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[8-9][\\.0-9A-Za-z]*")
# Versions beginning with 3.8 do not support component ipa
@ -155,8 +156,9 @@ else()
list(APPEND LLVM_FIND_COMPONENTS "debuginfo")
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-8][\\.0-9A-Za-z]*")
# Versions below 3.9 do not support components debuginfocodeview
# Versions below 3.9 do not support components debuginfocodeview, globalisel
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfocodeview" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "globalisel" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[8-9][\\.0-9A-Za-z]*")
# Versions beginning with 3.8 do not support component ipa

View file

@ -17,32 +17,97 @@
#include "gen/abi-generic.h"
#include "gen/abi-aarch64.h"
namespace {
struct CompositeToArray64 : ABIRewrite {
LLValue *get(Type *dty, LLValue *v) override {
Logger::println("rewriting i64 array -> as %s", dty->toChars());
LLValue *lval = DtoRawAlloca(v->getType(), 0);
DtoStore(v, lval);
LLType *pTy = getPtrToType(DtoType(dty));
return DtoLoad(DtoBitCast(lval, pTy), "get-result");
}
LLValue *put(DValue *dv) override {
Type *dty = dv->getType();
Logger::println("rewriting %s -> as i64 array", dty->toChars());
LLType *t = type(dty, nullptr);
return DtoLoad(DtoBitCast(dv->getRVal(), getPtrToType(t)));
}
LLType *type(Type *t, LLType *) override {
// An i64 array that will hold Type 't'
size_t sz = (t->size() + 7) / 8;
return LLArrayType::get(LLIntegerType::get(gIR->context(), 64), sz);
}
};
}
struct AArch64TargetABI : TargetABI {
HFAToArray hfaToArray;
CompositeToArray64 compositeToArray64;
IntegerRewrite integerRewrite;
bool returnInArg(TypeFunction *tf) override {
if (tf->isref) {
return false;
}
// Return structs and static arrays on the stack. The latter is needed
// because otherwise LLVM tries to actually return the array in a number
// of physical registers, which leads, depending on the target, to
// either horrendous codegen or backend crashes.
Type *rt = tf->next->toBasetype();
return (rt->ty == Tstruct || rt->ty == Tsarray);
// FIXME
if (tf->linkage == LINKd)
return rt->ty == Tsarray || rt->ty == Tstruct;
return rt->ty == Tsarray ||
(rt->ty == Tstruct && rt->size() > 16 && !isHFA((TypeStruct *)rt));
}
bool passByVal(Type *t) override { return t->toBasetype()->ty == Tstruct; }
bool passByVal(Type *t) override {
t = t->toBasetype();
return t->ty == Tsarray ||
(t->ty == Tstruct && t->size() > 16 && !isHFA((TypeStruct *)t));
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
Type *retTy = fty.ret->type->toBasetype();
if (!fty.ret->byref && retTy->ty == Tstruct) {
// Rewrite HFAs only because union HFAs are turned into IR types that are
// non-HFA and messes up register selection
if (isHFA((TypeStruct *)retTy, &fty.ret->ltype)) {
fty.ret->rewrite = &hfaToArray;
fty.ret->ltype = hfaToArray.type(fty.ret->type, fty.ret->ltype);
}
else {
fty.ret->rewrite = &integerRewrite;
fty.ret->ltype = integerRewrite.type(fty.ret->type, fty.ret->ltype);
}
}
void rewriteFunctionType(TypeFunction *t, IrFuncTy &fty) override {
for (auto arg : fty.args) {
if (!arg->byref) {
if (!arg->byref)
rewriteArgument(fty, *arg);
}
else if (passByVal(arg->type))
arg->attrs.remove(LLAttribute::ByVal);
}
}
void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override {
// FIXME
Type *ty = arg.type->toBasetype();
if (ty->ty == Tstruct || ty->ty == Tsarray) {
// Rewrite HFAs only because union HFAs are turned into IR types that are
// non-HFA and messes up register selection
if (ty->ty == Tstruct && isHFA((TypeStruct *)ty, &arg.ltype)) {
arg.rewrite = &hfaToArray;
arg.ltype = hfaToArray.type(arg.type, arg.ltype);
}
else {
arg.rewrite = &compositeToArray64;
arg.ltype = compositeToArray64.type(arg.type, arg.ltype);
}
}
}
/**

View file

@ -119,7 +119,7 @@ struct RemoveStructPadding : ABIRewrite {
*/
struct IntegerRewrite : ABIRewrite {
static LLType *getIntegerType(unsigned minSizeInBytes) {
if (minSizeInBytes > 8) {
if (minSizeInBytes > 16) {
return nullptr;
}
@ -136,6 +136,15 @@ struct IntegerRewrite : ABIRewrite {
case 7:
size = 8;
break;
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
size = 16;
break;
default:
break;
}

View file

@ -195,6 +195,9 @@ bool TargetABI::isHFA(TypeStruct *t, llvm::Type **rewriteType) {
case 8:
floatType = llvm::Type::getDoubleTy(gIR->context());
break;
case 16:
floatType = llvm::Type::getFP128Ty(gIR->context());
break;
default:
llvm_unreachable("Unexpected size for float type");
}

View file

@ -40,12 +40,6 @@
extern llvm::TargetMachine *gTargetMachine;
using namespace llvm;
// Allow the user to specify specific optimizations to run.
static cl::list<const PassInfo *, bool, PassNameParser>
passList(cl::desc("Running specific optimizations:"),
cl::Hidden // to clean up --help output
);
static cl::opt<signed char> optimizeLevel(
cl::desc("Setting the optimization level:"), cl::ZeroOrMore,
cl::values(
@ -384,37 +378,7 @@ bool ldc_optimize_module(llvm::Module *M) {
mpm.add(createStripSymbolsPass(true));
}
bool defaultsAdded = false;
// Create a new optimization pass for each one specified on the command line
for (unsigned i = 0; i < passList.size(); ++i) {
if (optimizeLevel &&
optimizeLevel.getPosition() < passList.getPosition(i)) {
addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());
defaultsAdded = true;
}
const PassInfo *passInf = passList[i];
Pass *pass = nullptr;
if (passInf->getNormalCtor()) {
pass = passInf->getNormalCtor()();
} else {
const char *arg = passInf->getPassArgument(); // may return null
if (arg) {
error(Loc(), "Can't create pass '-%s' (%s)", arg, pass->getPassName());
} else {
error(Loc(), "Can't create pass (%s)", pass->getPassName());
}
llvm_unreachable("pass creation failed");
}
if (pass) {
addPass(mpm, pass);
}
}
// Add the default passes for the specified optimization level.
if (!defaultsAdded) {
addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel());
}
// Run per-function passes.
fpm.doInitialization();

@ -1 +1 @@
Subproject commit 7e34fc3354306187165f4161cdf895974a7eb3d6
Subproject commit 1afd76758971d21bbcf520dd54abed2bf972f4ed

@ -1 +1 @@
Subproject commit cace03d663aedb39f83733931e29f031dfa4f36d
Subproject commit c50e99d70e8756f7991936d4419af458e025d54b

@ -1 +1 @@
Subproject commit 1ed287b135cbdefcb3a81ec94fc12c41cbbd5b31
Subproject commit 6dfdabdba37caf5526a7f9d55d78e6f0c750f9f8