ldc/gen/llvmcompat.cpp
David Nadlinger 0a96aea868 Sort includes according to style guidelines:
1. Main include corresponding to .cpp file, if any.
 2. DMD and LDC includes.
 3. LLVM includes.
 4. System includes.

Also updated a few include guards to match the default format.
2013-02-07 21:20:55 +01:00

169 lines
5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//===-- llvmcompat.cpp ----------------------------------------------------===//
//
// LDC the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
#include "gen/llvmcompat.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Config/llvm-config.h"
#if LDC_LLVM_VER >= 303
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#else
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#if LDC_LLVM_VER == 302
#include "llvm/IRBuilder.h"
#else
#include "llvm/Support/IRBuilder.h"
#endif
#endif
#include <string>
#if LDC_LLVM_VER == 300
using namespace llvm;
std::string llvm::sys::getDefaultTargetTriple() {
return LLVM_HOSTTRIPLE;
}
Triple llvm::Triple__get32BitArchVariant(const std::string& triple) {
Triple T(triple);
switch (T.getArch()) {
case Triple::UnknownArch:
case Triple::msp430:
#if LDC_LLVM_VER == 300
case Triple::alpha:
case Triple::systemz:
#endif
T.setArch(Triple::UnknownArch);
break;
case Triple::amdil:
case Triple::arm:
case Triple::cellspu:
case Triple::le32:
case Triple::mblaze:
case Triple::mips:
case Triple::mipsel:
case Triple::ppc:
case Triple::sparc:
case Triple::tce:
case Triple::thumb:
case Triple::x86:
case Triple::xcore:
#if LDC_LLVM_VER == 300
case Triple::bfin:
#endif
// Already 32-bit.
break;
case Triple::mips64: T.setArch(Triple::mips); break;
case Triple::mips64el: T.setArch(Triple::mipsel); break;
case Triple::ppc64: T.setArch(Triple::ppc); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
case Triple::x86_64: T.setArch(Triple::x86); break;
#if LDC_LLVM_VER == 300
case Triple::ptx64: T.setArch(Triple::ptx32); break;
#endif
}
return T;
}
Triple llvm::Triple__get64BitArchVariant(const std::string& triple) {
Triple T(triple);
switch (T.getArch()) {
case Triple::UnknownArch:
case Triple::amdil:
case Triple::arm:
case Triple::cellspu:
case Triple::le32:
case Triple::mblaze:
case Triple::msp430:
case Triple::tce:
case Triple::thumb:
case Triple::xcore:
#if LDC_LLVM_VER == 300
case Triple::bfin:
#endif
T.setArch(Triple::UnknownArch);
break;
#if LDC_LLVM_VER == 300
case Triple::alpha:
case Triple::systemz:
#endif
case Triple::mips64:
case Triple::mips64el:
case Triple::ppc64:
case Triple::sparcv9:
case Triple::x86_64:
// Already 64-bit.
break;
case Triple::mips: T.setArch(Triple::mips64); break;
case Triple::mipsel: T.setArch(Triple::mips64el); break;
case Triple::ppc: T.setArch(Triple::ppc64); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
case Triple::x86: T.setArch(Triple::x86_64); break;
#if LDC_LLVM_VER == 300
case Triple::ptx32: T.setArch(Triple::ptx64); break;
#endif
}
return T;
}
static void appendToGlobalArray(const char *Array,
Module &M, Function *F, int Priority) {
IRBuilder<> IRB(M.getContext());
FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);
StructType *Ty = StructType::get(
IRB.getInt32Ty(), PointerType::getUnqual(FnTy), NULL);
Constant *RuntimeCtorInit = ConstantStruct::get(
Ty, IRB.getInt32(Priority), F, NULL);
// Get the current set of static global constructors and add the new ctor
// to the list.
SmallVector<Constant *, 16> CurrentCtors;
if (GlobalVariable * GVCtor = M.getNamedGlobal(Array)) {
if (Constant *Init = GVCtor->getInitializer()) {
unsigned n = Init->getNumOperands();
CurrentCtors.reserve(n + 1);
for (unsigned i = 0; i != n; ++i)
CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
}
GVCtor->eraseFromParent();
}
CurrentCtors.push_back(RuntimeCtorInit);
// Create a new initializer.
ArrayType *AT = ArrayType::get(RuntimeCtorInit->getType(),
CurrentCtors.size());
Constant *NewInit = ConstantArray::get(AT, CurrentCtors);
// Create the new global variable and replace all uses of
// the old global variable with the new one.
(void)new GlobalVariable(M, NewInit->getType(), false,
GlobalValue::AppendingLinkage, NewInit, Array);
}
void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) {
appendToGlobalArray("llvm.global_ctors", M, F, Priority);
}
void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority) {
appendToGlobalArray("llvm.global_dtors", M, F, Priority);
}
#endif