Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2731010
llvmlayer.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Mar 14, 2:27 AM
Size
7 KB
Mime Type
text/x-c++
Expires
Mon, Mar 16, 2:27 AM (1 d, 15 h)
Engine
blob
Format
Raw Data
Handle
243778
Attached To
rXR Xreate
llvmlayer.cpp
View Options
#include "ast.h"
#include "llvmlayer.h"
#include "ExternLayer.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/Support/TargetSelect.h"
#include <iostream>
#include <cmath>
using namespace llvm;
using namespace xreate;
using namespace std;
LLVMLayer::LLVMLayer(AST* root)
: ast(root), builder(getGlobalContext()) {
module = new llvm::Module(root->getModuleName(), llvm::getGlobalContext());
layerExtern = new ExternLayer(this);
layerExtern->init(root);
}
void*
LLVMLayer::getFunctionPointer(llvm::Function* function){
uint64_t entryAddr = jit->getFunctionAddress(function->getName().str());
return (void*) entryAddr;
}
void
LLVMLayer::initJit(){
std::string ErrStr;
LLVMInitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::EngineBuilder builder((std::unique_ptr<llvm::Module>(module)));
jit = builder
.setEngineKind(llvm::EngineKind::JIT)
.setErrorStr(&ErrStr)
.setVerifyModules(true)
.create();
}
void
LLVMLayer::print(){
llvm::PassManager<llvm::Module> PM;
PM.addPass(llvm::PrintModulePass(llvm::outs(), "banner"));
PM.run(*module);
}
llvm::BasicBlock*
LLVMLayer::initExceptionBlock(llvm::BasicBlock* blockException){
initExceptionsSupport();
PointerType* tyInt8P = PointerType::getInt8PtrTy(llvm::getGlobalContext());
Value* nullInt8P = llvm::ConstantPointerNull::get(tyInt8P);
builder.SetInsertPoint(blockException);
llvm::Function* fAllocate = module->getFunction("__cxa_allocate_exception");
llvm::Function* fThrow = module->getFunction("__cxa_throw");
auto exception = builder.CreateCall(fAllocate, ConstantInt::get(IntegerType::getInt64Ty(getGlobalContext()), 4));
vector<Value*> throwParams{exception, nullInt8P, nullInt8P};
builder.CreateCall(fThrow, ArrayRef<Value*>(throwParams));
builder.CreateUnreachable();
return blockException;
}
void
LLVMLayer::moveToGarbage(void *o)
{
__garbage.push_back(o);
}
llvm::Type*
LLVMLayer::
toLLVMType(const ExpandedType& ty) const {
std::map<int, llvm::StructType*> empty;
return toLLVMType(ty, empty);
}
llvm::Type*
LLVMLayer::
toLLVMType(const ExpandedType& ty, std::map<int, llvm::StructType*>& conjuctions) const
{
TypeAnnotation t = ty;
switch (t.__operator)
{
case TypeOperator::ARRAY:
{
assert(t.__operands.size()==1);
TypeAnnotation elTy = t.__operands.at(0);
return llvm::ArrayType::get(toLLVMType(ExpandedType(move(elTy)), conjuctions), t.__size);
}
case TypeOperator::STRUCT:
case TypeOperator::TUPLE:
{
assert(t.__operands.size());
std::vector<llvm::Type*> pack_;
pack_.reserve(t.__operands.size());
std::transform(t.__operands.begin(), t.__operands.end(), std::inserter(pack_, pack_.end()),
[this, &conjuctions](const TypeAnnotation& t){
return toLLVMType(ExpandedType(TypeAnnotation(t)), conjuctions);
});
llvm::ArrayRef<llvm::Type*> pack(pack_);
//process recursive types:
if (conjuctions.count(t.conjuctionId)) {
auto result = conjuctions[t.conjuctionId];
result->setBody(pack, false);
return result;
}
return llvm::StructType::get(llvm::getGlobalContext(), pack, false);
};
case TypeOperator::LINK: {
llvm::StructType* conjuction = llvm::StructType::create(llvm::getGlobalContext());
int id = t.conjuctionId;
conjuctions.emplace(id, conjuction);
return conjuction;
};
case TypeOperator::CALL:
{
assert(false);
};
case TypeOperator::CUSTOM:
{
//Look in extern types
clang::QualType qt = layerExtern->lookupType(t.__valueCustom);
return layerExtern->toLLVMType(qt);
};
case TypeOperator::VARIANT: {
int size = t.fields.size();
assert(size);
int bitcount = ceil(log2(size));
return llvm::Type::getIntNTy(llvm::getGlobalContext(), bitcount);
}
case TypeOperator::NONE: {
switch (t.__value) {
case TypePrimitive::I32:
case TypePrimitive::Int:
case TypePrimitive::Num:
return llvm::Type::getInt32Ty(llvm::getGlobalContext());
case TypePrimitive::Bool:
return llvm::Type::getInt1Ty(llvm::getGlobalContext());
case TypePrimitive::I8:
return llvm::Type::getInt8Ty(llvm::getGlobalContext());
case TypePrimitive::I64:
return llvm::Type::getInt64Ty(llvm::getGlobalContext());
case TypePrimitive::Float:
return llvm::Type::getDoubleTy(llvm::getGlobalContext());
case TypePrimitive::String:
return llvm::Type::getInt8PtrTy(llvm::getGlobalContext());
default:
assert(false);
}
}
default:
assert(false);
}
assert(false);
return nullptr;
}
void
LLVMLayer::initExceptionsSupport(){
Type* typInt8Ptr = PointerType::get(IntegerType::get(module->getContext(), 8), 0);
if (!module->getFunction("__cxa_throw")) {
std::vector<Type*> fThrowSignature{typInt8Ptr, typInt8Ptr, typInt8Ptr};
FunctionType* tyFThrow = FunctionType::get(
/*Result=*/Type::getVoidTy(module->getContext()),
/*Params=*/fThrowSignature,
/*isVarArg=*/false);
llvm::Function::Create(
/*Type=*/tyFThrow,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"__cxa_throw", module); // (external, no body)
}
if (!module->getFunction("__cxa_allocate_exception")) {
std::vector<Type*>fAllocateSignature{IntegerType::get(module->getContext(), 64)};
FunctionType* tyFAllocate = FunctionType::get(
/*Result=*/typInt8Ptr,
/*Params=*/fAllocateSignature,
/*isVarArg=*/false);
llvm::Function::Create(
/*Type=*/tyFAllocate,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"__cxa_allocate_exception", module); // (external, no body)
}
}
bool TypeUtils::isStruct(const ExpandedType& ty){
const TypeAnnotation& t = ty.get();
if (t.__operator==TypeOperator::STRUCT) {
return true;
}
if (t.__operator != TypeOperator::CUSTOM) {
return false;
}
clang::QualType tqual = llvm->layerExtern->lookupType(t.__valueCustom);
const clang::Type * raw = tqual.getTypePtr();
// TODO skip ALL the pointers until non-pointer type found
if (raw->isStructureType()) return true;
if (!raw->isAnyPointerType()) return false;
clang::QualType pointee = raw->getPointeeType();
return pointee->isStructureType();
}
bool TypeUtils::isPointer(const ExpandedType &ty) {
if (ty.get().__operator != TypeOperator::CUSTOM) return false;
clang::QualType qt = llvm->layerExtern->lookupType(ty.get().__valueCustom);
return llvm->layerExtern->isPointer(qt);
}
std::vector<std::string>
TypeUtils::getStructFields(const ExpandedType &t) {
return (t.get().__operator == TypeOperator::STRUCT)
? t.get().fields
: llvm->layerExtern->getStructFields(
llvm->layerExtern->lookupType(t.get().__valueCustom));
}
Event Timeline
Log In to Comment