Commit 4301ada8 authored by Victor Yacovlev's avatar Victor Yacovlev

LLVM: Debian 8.x support

parent c5805662
......@@ -13,6 +13,8 @@
# Llvm_INCLUDE_DIR
# Llvm_LIBRARIES
# Llvm_DEFINITIONS
# Llvm_VERSION
# Llvm_API_VERSION
# This module relies on following variable to search
# LLVM_ROOT
......@@ -21,6 +23,13 @@ find_program(Llvm_CONFIG_EXECUTABLE NAMES llvm-config PATHS ${LLVM_ROOT} ${LLVM_
if(Llvm_CONFIG_EXECUTABLE)
exec_program(${Llvm_CONFIG_EXECUTABLE} ARGS "--version" OUTPUT_VARIABLE Llvm_VERSION)
string(REPLACE "." ";" Llvm_VERSION_LIST ${Llvm_VERSION})
list(GET Llvm_VERSION_LIST 0 Llvm_VERSION_MAJOR)
list(GET Llvm_VERSION_LIST 1 Llvm_VERSION_MINOR)
list(GET Llvm_VERSION_LIST 2 Llvm_VERSION_PATCH)
set(Llvm_API_VERSION "${Llvm_VERSION_MAJOR}.${Llvm_VERSION_MINOR}")
if(EXISTS /usr/${LIB_BASENAME}/llvm/libLLVM-${Llvm_VERSION}.so)
# Fedora-specific .so-version
set(Llvm_LIBRARIES "-L/usr/${LIB_BASENAME}/llvm -lLLVM-${Llvm_VERSION}")
......@@ -40,6 +49,8 @@ if(Llvm_CONFIG_EXECUTABLE)
set(Llvm_REQUEST_STRING "${LLVM_REQUEST_STRING} ${component}")
endforeach()
endif()
exec_program(${Llvm_CONFIG_EXECUTABLE} ARGS "--ldflags" OUTPUT_VARIABLE Llvm_LD_FLAGS_1)
string(STRIP ${Llvm_LD_FLAGS_1} Llvm_LD_FLAGS)
exec_program(${Llvm_CONFIG_EXECUTABLE} ARGS "--libs ${Llvm_REQUEST_STRING}" OUTPUT_VARIABLE Llvm_LIBRARIES_STRING)
string(REPLACE " " ";" Llvm_LIBS_LIST ${Llvm_LIBRARIES_STRING})
foreach(_lib ${Llvm_LIBS_LIST})
......@@ -51,7 +62,7 @@ if(Llvm_CONFIG_EXECUTABLE)
set(Llvm_LIBRARIES "${Llvm_LIBRARIES};${_lib}")
endforeach()
if(NOT WIN32)
set(Llvm_LIBRARIES "${Llvm_LIBRARIES};dl;m")
set(Llvm_LIBRARIES "${Llvm_LIBRARIES};dl;m;tinfo")
endif(NOT WIN32)
if(WIN32)
link_directories("${LLVM_ROOT}/lib")
......@@ -66,6 +77,7 @@ if(Llvm_CONFIG_EXECUTABLE)
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LLVM Llvm_LIBRARIES Llvm_DEFINITIONS Llvm_INCLUDE_DIR)
mark_as_advanced(Llvm_LIBRARIES Llvm_DEFINITIONS Llvm_INCLUDE_DIR)
find_package_handle_standard_args(LLVM Llvm_LIBRARIES Llvm_LD_FLAGS Llvm_DEFINITIONS Llvm_INCLUDE_DIR)
mark_as_advanced(Llvm_LIBRARIES Llvm_DEFINITIONS Llvm_INCLUDE_DIR Llvm_VERSION Llvm_API_VERSION)
......@@ -60,6 +60,7 @@ copySpecFile(LLVMCodeGenerator)
add_library(LLVMCodeGenerator SHARED ${MOC_SOURCES} ${SOURCES})
#handleTranslation(LLVMCodeGenerator)
target_link_libraries(LLVMCodeGenerator
${Llvm_LD_FLAGS}
${Llvm_LIBRARIES}
${DEP_LIBS}
${QT_LIBRARIES}
......@@ -134,6 +135,7 @@ else()
-o ${SHARE_PATH}/llvmcodegenerator/stdlib.bc
${CMAKE_CURRENT_SOURCE_DIR}/stdlib_c.cpp
)
add_custom_target(llvm-stdlib ALL DEPENDS ${SHARE_PATH}/llvmcodegenerator/stdlib.bc)
if(CMAKE_BUILD_TYPE MATCHES Debug)
add_custom_command(
OUTPUT ${SHARE_PATH}/llvmcodegenerator/stdlib_debug.o
......@@ -143,6 +145,7 @@ else()
-o ${SHARE_PATH}/llvmcodegenerator/stdlib_debug.o
${CMAKE_CURRENT_SOURCE_DIR}/stdlib_c.cpp
)
add_custom_target(llvm-stdlib-debug ALL DEPENDS ${SHARE_PATH}/llvmcodegenerator/stdlib_debug.o)
endif()
endif(WIN32)
......
#include "llvm_function.h"
#include "llvm_type.h"
#include "llvm_module.h"
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Function.h>
namespace LLVM {
llvm::Function* FunctionRef::rawPtr() const
{
return d;
}
QByteArray FunctionRef::name() const
{
llvm::StringRef ls = rawPtr()->getName();
return QByteArray(ls.begin(), ls.size());
}
bool FunctionRef::hasExternalLinkage() const
{
return rawPtr()->hasExternalLinkage();
}
FunctionRef FunctionRef::create(
TypeRef returnType,
Visibility visibility,
const QByteArray &name,
const QVector<TypeRef> &argTypes,
const QVector<QByteArray> &argNames,
bool firstArgIsReturnValuePointer,
ModuleRef & parent,
llvm::LLVMContext* ctx
)
{
llvm::Type *lt = returnType.rawPtr();
std::vector<llvm::Type*> largTypes(argTypes.size());
for (int i=0; i<argTypes.size(); ++i) {
llvm::Type *at = (llvm::Type*) argTypes[i].rawPtr();
largTypes[i] = at;
}
llvm::FunctionType * lft = largTypes.empty()
? llvm::FunctionType::get(lt, false)
: llvm::FunctionType::get(lt, largTypes, false)
;
llvm::GlobalValue::LinkageTypes link =
VS_Extern==visibility
? llvm::GlobalValue::ExternalLinkage
: llvm::GlobalValue::PrivateLinkage
;
std::string lname(name.constData(), name.size());
llvm::Module *lm = (llvm::Module*) parent.rawPtr();
llvm::Function *lf = llvm::Function::Create(
lft, link, lname, lm
);
lf->addFnAttr(llvm::Attribute::NoUnwind);
lf->addFnAttr(llvm::Attribute::UWTable);
typedef llvm::Function::ArgumentListType::iterator AIt;
int argNumber = 0;
for (AIt it=lf->getArgumentList().begin();
argNumber<argNames.size() ; ++argNumber, ++it)
{
const std::string argName(argNames[argNumber].constData());
it->setName(argName);
}
if (firstArgIsReturnValuePointer) {
llvm::Argument & firstArg = lf->getArgumentList().front();
llvm::AttrBuilder abuilder;
abuilder.addAttribute(llvm::Attribute::StructRet);
abuilder.addAttribute(llvm::Attribute::NoAlias);
firstArg.addAttr(llvm::AttributeSet::get(*ctx, 0, abuilder));
firstArg.addAttr(llvm::AttributeSet::get(*ctx, 1, abuilder));
}
FunctionRef result;
result.d = (lf);
return result;
}
void FunctionRef::copyToModule(ModuleRef & target)
{
llvm::FunctionType * ft = d->getFunctionType();
llvm::StringRef fn = d->getName();
llvm::GlobalValue::LinkageTypes fl = d->getLinkage();
llvm::Module* tm = target.rawPtr();
llvm::Function::Create(ft,fl,fn,tm);
}
LLVM::FunctionRef::operator bool() const
{
return 0 != rawPtr();
}
bool FunctionRef::operator ==(const FunctionRef &other) const
{
return rawPtr() == other.rawPtr();
}
llvm::CallInst *FunctionRef::createCallInstruction(void *b, const QVector<llvm::Value *> &values)
{
llvm::IRBuilder<> * builder =
reinterpret_cast<llvm::IRBuilder<>*>(b);
std::vector<llvm::Value*> callArgs(values.size());
std::copy(values.begin(), values.end(), callArgs.begin());
return builder->CreateCall(d, callArgs);
}
}
#include "llvm_module.h"
#include <memory>
#include <string>
#include <QByteArray>
#include <QCoreApplication>
#include <QVariant>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/Linker/Linker.h>
#include <llvm/Support/ErrorOr.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/AsmParser/Parser.h>
namespace LLVM {
void ModuleRef::linkInto(ModuleRef & dest)
{
llvm::Linker::LinkModules(dest.rawPtr(), d.get(), 0, 0);
d.reset(); // Make semantics like in LLVM 3.7+
}
QByteArray ModuleRef::textRepresentation() const
{
std::string buf;
llvm::raw_string_ostream ostream(buf);
d->print(ostream, 0);
ostream.flush();
buf = ostream.str();
return QByteArray(buf.c_str(), buf.size());
}
QByteArray ModuleRef::binaryRepresentation() const
{
std::string buf;
llvm::raw_string_ostream ostream(buf);
llvm::WriteBitcodeToFile(d.get(), ostream);
ostream.flush();
buf = ostream.str();
return QByteArray(buf.c_str(), buf.size());
}
LLVM::ModuleRef::operator bool() const
{
if (!d) return false;
return 0 != rawPtr();
}
bool ModuleRef::operator ==(const ModuleRef other) const
{
if (!d) {
return !other.d;
}
else {
return d.get() == other.d.get();
}
}
ModuleRef::ModuleRef()
{
}
ModuleRef::ModuleRef(ModuleRef && src)
{
d = std::move(src.d);
}
ModuleRef &ModuleRef::operator=(ModuleRef && src)
{
d = std::move(src.d);
return *this;
}
ModuleRef::~ModuleRef()
{
}
llvm::Module * ModuleRef::rawPtr() const
{
if (d) {
return d.get();
}
else {
return 0;
}
}
ModuleRef ModuleRef::create(llvm::LLVMContext *ctx)
{
ModuleRef result;
result.d =
std::unique_ptr<llvm::Module> (
new llvm::Module("", *ctx)
);
return result;
}
ModuleRef ModuleRef::fromTextRepresentation(const QByteArray &text, llvm::LLVMContext * ctx)
{
llvm::SMDiagnostic lerr;
ModuleRef result;
result.d = std::unique_ptr<llvm::Module>(
llvm::ParseAssemblyString(text.constData(), 0, lerr, *ctx));
if (! result.d ) {
lerr.print("kumir2-llvmc", llvm::errs());
qApp->setProperty("returnCode", QVariant(5));
qApp->quit();
}
return result;
}
ModuleRef ModuleRef::fromBinaryRepresentation(const QByteArray &data,
const QString &fileName,
llvm::LLVMContext * ctx)
{
std::string lFileName(fileName.toUtf8().constData());
std::string lContents(data.constData(), data.size());
std::unique_ptr<llvm::MemoryBuffer> unitBuffer = std::unique_ptr<llvm::MemoryBuffer>(
llvm::MemoryBuffer::getMemBufferCopy(
lContents, lFileName
));
llvm::ErrorOr<llvm::Module*> errorOrUnit =
llvm::parseBitcodeFile(unitBuffer.get(), *ctx);
ModuleRef result;
if (errorOrUnit) {
result.d.reset(errorOrUnit.get());
}
return result;
}
TypeRef ModuleRef::getType(const QByteArray &name) const
{
llvm::StructType * t = d->getTypeByName(std::string(name.constData(), name.size()));
TypeRef result;
result.d = (t);
return result;
}
QList<FunctionRef> ModuleRef::functions() const
{
typedef llvm::Module::iterator Fit;
QList<FunctionRef> result;
llvm::Module* lm = rawPtr();
for (Fit it=lm->begin(); it!=lm->end(); ++it) {
llvm::Function & func = *it;
FunctionRef ref;
ref.d = (&func);
result.push_back(ref);
}
return result;
}
FunctionRef ModuleRef::getFunction(const QByteArray &name) const
{
FunctionRef result;
if (d) {
llvm::Module * l = d.get();
llvm::Function *lf = l->getFunction(std::string(name.constData(), name.size()));
result.d = lf;
}
return result;
}
}
#include "llvm_type.h"
#include <llvm/IR/Type.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/LLVMContext.h>
namespace LLVM {
llvm::Type * TypeRef::rawPtr() const
{
return d;
}
TypeRef TypeRef::getGeneric(GenericType type, llvm::LLVMContext * ctx)
{
llvm::Type * t = 0;
switch (type) {
case TY_Void:
t = llvm::Type::getVoidTy(*ctx);
break;
case TY_Int:
t = llvm::Type::getInt32Ty(*ctx);
break;
case TY_Real:
t = llvm::Type::getDoubleTy(*ctx);
break;
case TY_Byte:
t = llvm::Type::getInt8Ty(*ctx);
break;
case TY_CStr:
t = llvm::Type::getInt8PtrTy(*ctx);
break;
default:
t = 0;
break;
}
TypeRef result;
result.d = (t);
return result;
}
LLVM::TypeRef::operator bool() const
{
return bool(d);
}
bool TypeRef::operator ==(const TypeRef &other) const
{
return rawPtr()==other.rawPtr();
}
TypeRef TypeRef::pointerTo() const
{
llvm::Type * me = d;
TypeRef result;
result.d = (me->getPointerTo());
return result;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment