mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 09:00:33 +03:00
Backport of "Avoid using llvm::Linker" to master.
See pull request #974 for the original code.
This commit is contained in:
parent
d7347a5829
commit
d1e764cec1
39 changed files with 753 additions and 812 deletions
|
@ -8,6 +8,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "gen/functions.h"
|
||||
|
||||
#include "aggregate.h"
|
||||
#include "declaration.h"
|
||||
#include "id.h"
|
||||
|
@ -20,6 +21,7 @@
|
|||
#include "gen/arrays.h"
|
||||
#include "gen/classes.h"
|
||||
#include "gen/dvalue.h"
|
||||
#include "gen/inlineir.h"
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/linkage.h"
|
||||
#include "gen/llvm.h"
|
||||
|
@ -30,11 +32,7 @@
|
|||
#include "gen/pragma.h"
|
||||
#include "gen/runtime.h"
|
||||
#include "gen/tollvm.h"
|
||||
#if LDC_LLVM_VER >= 305
|
||||
#include "llvm/Linker/Linker.h"
|
||||
#else
|
||||
#include "llvm/Linker.h"
|
||||
#endif
|
||||
#include "ir/irmodule.h"
|
||||
#if LDC_LLVM_VER >= 303
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#else
|
||||
|
@ -224,114 +222,6 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#if LDC_LLVM_VER >= 305
|
||||
#include "llvm/AsmParser/Parser.h"
|
||||
#else
|
||||
#include "llvm/Assembly/Parser.h"
|
||||
#endif
|
||||
|
||||
LLFunction* DtoInlineIRFunction(FuncDeclaration* fdecl)
|
||||
{
|
||||
const char* mangled_name = mangleExact(fdecl);
|
||||
TemplateInstance* tinst = fdecl->parent->isTemplateInstance();
|
||||
assert(tinst);
|
||||
|
||||
Objects& objs = tinst->tdtypes;
|
||||
assert(objs.dim == 3);
|
||||
|
||||
Expression* a0 = isExpression(objs[0]);
|
||||
assert(a0);
|
||||
StringExp* strexp = a0->toStringExp();
|
||||
assert(strexp);
|
||||
assert(strexp->sz == 1);
|
||||
std::string code(static_cast<char*>(strexp->string), strexp->len);
|
||||
|
||||
Type* ret = isType(objs[1]);
|
||||
assert(ret);
|
||||
|
||||
Tuple* a2 = isTuple(objs[2]);
|
||||
assert(a2);
|
||||
Objects& arg_types = a2->objects;
|
||||
|
||||
std::string str;
|
||||
llvm::raw_string_ostream stream(str);
|
||||
stream << "define " << *DtoType(ret) << " @" << mangled_name << "(";
|
||||
|
||||
for(size_t i = 0; ;)
|
||||
{
|
||||
Type* ty = isType(arg_types[i]);
|
||||
//assert(ty);
|
||||
if(!ty)
|
||||
{
|
||||
error(tinst->loc,
|
||||
"All parameters of a template defined with pragma llvm_inline_ir, except for the first one, should be types");
|
||||
fatal();
|
||||
}
|
||||
stream << *DtoType(ty);
|
||||
|
||||
i++;
|
||||
if(i >= arg_types.dim)
|
||||
break;
|
||||
|
||||
stream << ", ";
|
||||
}
|
||||
|
||||
if(ret->ty == Tvoid)
|
||||
code.append("\nret void");
|
||||
|
||||
stream << ")\n{\n" << code << "\n}";
|
||||
|
||||
llvm::SMDiagnostic err;
|
||||
|
||||
#if LDC_LLVM_VER >= 306
|
||||
std::unique_ptr<llvm::Module> m = llvm::parseAssemblyString(
|
||||
stream.str().c_str(), err, gIR->context());
|
||||
#elif LDC_LLVM_VER >= 303
|
||||
llvm::Module* m = llvm::ParseAssemblyString(
|
||||
stream.str().c_str(), NULL, err, gIR->context());
|
||||
#else
|
||||
llvm::ParseAssemblyString(
|
||||
stream.str().c_str(), gIR->module, err, gIR->context());
|
||||
#endif
|
||||
|
||||
std::string errstr = err.getMessage();
|
||||
if(errstr != "")
|
||||
error(tinst->loc,
|
||||
"can't parse inline LLVM IR:\n%s\n%s\n%s\nThe input string was: \n%s",
|
||||
#if LDC_LLVM_VER >= 303
|
||||
err.getLineContents().str().c_str(),
|
||||
#else
|
||||
err.getLineContents().c_str(),
|
||||
#endif
|
||||
(std::string(err.getColumnNo(), ' ') + '^').c_str(),
|
||||
errstr.c_str(), stream.str().c_str());
|
||||
|
||||
#if LDC_LLVM_VER >= 306
|
||||
llvm::Linker(gIR->module).linkInModule(m.get());
|
||||
#else
|
||||
#if LDC_LLVM_VER >= 303
|
||||
std::string errstr2 = "";
|
||||
#if LDC_LLVM_VER >= 306
|
||||
llvm::Linker(gIR->module).linkInModule(m.get(), &errstr2);
|
||||
#else
|
||||
llvm::Linker(gIR->module).linkInModule(m, &errstr2);
|
||||
#endif
|
||||
if(errstr2 != "")
|
||||
error(tinst->loc,
|
||||
"Error when linking in llvm inline ir: %s", errstr2.c_str());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
LLFunction* fun = gIR->module->getFunction(mangled_name);
|
||||
fun->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
|
||||
fun->addFnAttr(LDC_ATTRIBUTE(AlwaysInline));
|
||||
return fun;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
|
||||
{
|
||||
IrFuncTy &irFty = getIrFunc(fdecl, true)->irFty;
|
||||
|
@ -595,7 +485,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
|
||||
// construct function
|
||||
LLFunctionType* functype = DtoFunctionType(fdecl);
|
||||
LLFunction* func = vafunc ? vafunc : gIR->module->getFunction(mangledName);
|
||||
LLFunction* func = vafunc ? vafunc : gIR->module.getFunction(mangledName);
|
||||
if (!func) {
|
||||
if(fdecl->llvmInternal == LLVMinline_ir)
|
||||
{
|
||||
|
@ -606,7 +496,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
// All function declarations are "external" - any other linkage type
|
||||
// is set when actually defining the function.
|
||||
func = LLFunction::Create(functype,
|
||||
llvm::GlobalValue::ExternalLinkage, mangledName, gIR->module);
|
||||
llvm::GlobalValue::ExternalLinkage, mangledName, &gIR->module);
|
||||
}
|
||||
} else if (func->getFunctionType() != functype) {
|
||||
error(fdecl->loc, "Function type does not match previously declared function with the same mangled name: %s", mangleExact(fdecl));
|
||||
|
@ -835,19 +725,21 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
assert(fd->ident != Id::empty);
|
||||
|
||||
if (fd->isUnitTestDeclaration()) {
|
||||
gIR->unitTests.push_back(fd);
|
||||
getIrModule(gIR->dmodule)->unitTests.push_back(fd);
|
||||
} else if (fd->isSharedStaticCtorDeclaration()) {
|
||||
gIR->sharedCtors.push_back(fd);
|
||||
getIrModule(gIR->dmodule)->sharedCtors.push_back(fd);
|
||||
} else if (StaticDtorDeclaration *dtorDecl = fd->isSharedStaticDtorDeclaration()) {
|
||||
gIR->sharedDtors.push_front(fd);
|
||||
if (dtorDecl->vgate)
|
||||
gIR->sharedGates.push_front(dtorDecl->vgate);
|
||||
getIrModule(gIR->dmodule)->sharedDtors.push_front(fd);
|
||||
if (dtorDecl->vgate) {
|
||||
getIrModule(gIR->dmodule)->sharedGates.push_front(dtorDecl->vgate);
|
||||
}
|
||||
} else if (fd->isStaticCtorDeclaration()) {
|
||||
gIR->ctors.push_back(fd);
|
||||
getIrModule(gIR->dmodule)->ctors.push_back(fd);
|
||||
} else if (StaticDtorDeclaration *dtorDecl = fd->isStaticDtorDeclaration()) {
|
||||
gIR->dtors.push_front(fd);
|
||||
if (dtorDecl->vgate)
|
||||
gIR->gates.push_front(dtorDecl->vgate);
|
||||
getIrModule(gIR->dmodule)->dtors.push_front(fd);
|
||||
if (dtorDecl->vgate) {
|
||||
getIrModule(gIR->dmodule)->gates.push_front(dtorDecl->vgate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -877,9 +769,6 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
IF_LOG Logger::println("Doing function body for: %s", fd->toChars());
|
||||
gIR->functions.push_back(irFunc);
|
||||
|
||||
if (fd->isMain())
|
||||
gIR->emitMain = true;
|
||||
|
||||
func->setLinkage(lowerFuncLinkage(fd));
|
||||
|
||||
// On x86_64, always set 'uwtable' for System V ABI compatibility.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue