Skip to content

Add ConstantAggregateZero ConstantExpr and a few more methods #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
112c2b8
Add ConstantExpr
vihanb Mar 2, 2018
b67b94b
Add a couple more methods
vihanb Mar 2, 2018
7547c2c
Add ConstantExpr.getBitCast
vihanb Mar 2, 2018
0242e53
Add DataLayout.getTypeAllocSize function
vihanb Mar 7, 2018
9e7208a
Add DataLayout.getTypeAllocSizeInBits
vihanb Mar 7, 2018
e078096
Add IntegerType class.
vihanb Mar 7, 2018
77dafe3
Merge branch 'add-getTypeAllocSize'
vihanb Mar 7, 2018
894dbf2
Add ConstantAggregateZero class
vihanb Mar 8, 2018
5c215c5
Add missing to IR
vihanb Mar 8, 2018
e066518
Add GEP for ConstantExpr
vihanb Mar 11, 2018
b3809c0
Use constant GEP.
vihanb Mar 11, 2018
366bb2e
Add IsNull call
vihanb Mar 22, 2018
fed76a6
Add unsigned remainder to IR builder
vihanb Mar 27, 2018
eac8051
Add casting functions
vihanb Apr 3, 2018
641984f
Merge remote-tracking branch 'upstream/master'
vihanb Oct 27, 2018
55f1f55
Merge remote-tracking branch 'upstream/master'
vihanb Nov 23, 2018
75ebf64
Add createIntToPtr and also address review comments
vihanb Dec 8, 2018
10cbb3a
Merge branch 'master' into master
vihanb Dec 12, 2018
170fc44
Fix tests and also add last method forgot to put
vihanb Dec 12, 2018
cac32ed
Add missing udiv
vihanb Dec 12, 2018
33eacb7
Oops
vihanb Dec 12, 2018
4690747
Fix IRBuilder tests, not sure why they were this way.
vihanb Dec 21, 2018
b45fd26
.bitWidth -> .getBitWidth() and other test fixes
vihanb Dec 21, 2018
a1ab7ba
Add floating point isNaN operation effectively
vihanb Jan 4, 2019
700295a
Add 'createUnreachable'
vihanb Jan 17, 2019
3357b27
Merge remote-tracking branch 'upstream/master'
vihanb May 14, 2019
76fad39
Merge remote-tracking branch 'refs/remotes/origin/master'
vihanb May 14, 2019
35b7014
Merge remote-tracking branch 'upstream/master'
vihanb May 18, 2019
9be0aa7
Add atomicRMW
vihanb Jun 8, 2019
827a1b3
Remove invalid fops for rmw operations.
vihanb Jul 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion llvm-node.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,22 @@ declare namespace llvm {
isAllOnesValue(): boolean;
}

class ConstantAggregateZero extends Constant {
static get(type: Type): Constant;

private constructor();
}

class ConstantExpr extends Constant {
static getBitCast(constant: Constant, type: Type): ConstantExpr

static getOr(constant1: Constant, constant2: Constant): ConstantExpr

static getPointerBitCastOrAddrSpaceCast(constant: Constant, type: Type): ConstantExpr

static getPointerCast(constant: Constant, type: Type): ConstantExpr
}

class ConstantFP extends Constant {
static get(context: LLVMContext, value: number): ConstantFP;

Expand Down Expand Up @@ -364,6 +380,10 @@ declare namespace llvm {

getTypeStoreSize(type: Type): number;

getTypeAllocSize(type: Type): number;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't find this method in the LLVM documentation nor that it is implemented in this PR. should this (and the following method be declared on DataLayout instead)?


getTypeAllocSizeInBits(type: Type): number;

getIntPtrType(context: LLVMContext, as: number): Type;
}

Expand Down Expand Up @@ -443,6 +463,7 @@ declare namespace llvm {

isArrayTy(): boolean;

isFloatingPointTy(): boolean;
isHalfTy(): boolean;

isPointerTy(): this is PointerType;
Expand All @@ -451,6 +472,7 @@ declare namespace llvm {

getPrimitiveSizeInBits(): number;


toString(): string;
}

Expand Down Expand Up @@ -576,6 +598,7 @@ declare namespace llvm {
createFSub(lhs: Value, rhs: Value, name?: string): Value;

createFPToSI(value: Value, type: Type, name?: string): Value;
createFPToUI(value: Value, type: Type, name?: string): Value;

createGlobalString(str: string, name?: string, addressSpace?: number): Value;

Expand Down Expand Up @@ -608,6 +631,8 @@ declare namespace llvm {

createICmpULT(lhs: Value, rhs: Value, name?: string): Value;

createIsNull(ptr: Value, name?: string): Value;

createLoad(ptr: Value, name?: string): Value;

createLShr(lhs: Value, rhs: Value, name?: string): Value;
Expand Down Expand Up @@ -646,10 +671,14 @@ declare namespace llvm {

createSRem(lhs: Value, rhs: Value, name?: string): Value;

CreateURem(lhs: Value, rhs: Value, name?: string): Value;
createURem(lhs: Value, rhs: Value, name?: string): Value;

createZExt(value: Value, destType: Type, name?: string): Value;

createZExtOrTrunc(value: Value, destType: Type, name?: string): Value;

createSExtOrTrunc(value: Value, destType: Type, name?: string): Value;

getInsertBlock(): BasicBlock | undefined;
}

Expand Down
67 changes: 67 additions & 0 deletions src/ir/constant-aggregate-zero.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "constant-aggregate-zero.h"
#include "type.h"

NAN_MODULE_INIT(ConstantAggregateZeroWrapper::Init) {
auto constantAggregateZero = Nan::GetFunction(Nan::New(constantAggregateZeroTemplate())).ToLocalChecked();

Nan::Set(target, Nan::New("ConstantAggregateZero").ToLocalChecked(), constantAggregateZero);
}

v8::Local<v8::Object> ConstantAggregateZeroWrapper::of(llvm::ConstantAggregateZero* constantAggregateZero) {
auto constructor = Nan::GetFunction(Nan::New(constantAggregateZeroTemplate())).ToLocalChecked();
v8::Local<v8::Value> args[1] = { Nan::New<v8::External> (constantAggregateZero) };

auto instance = Nan::NewInstance(constructor, 1, args).ToLocalChecked();

Nan::EscapableHandleScope escapableHandleScope {};
return escapableHandleScope.Escape(instance);
}

llvm::ConstantAggregateZero* ConstantAggregateZeroWrapper::getConstantAggregateZero() {
return static_cast<llvm::ConstantAggregateZero*>(getValue());
}

Nan::Persistent<v8::FunctionTemplate>& ConstantAggregateZeroWrapper::constantAggregateZeroTemplate() {
static Nan::Persistent<v8::FunctionTemplate> functionTemplate {};

if (functionTemplate.IsEmpty()) {
v8::Local<v8::FunctionTemplate> localTemplate = Nan::New<v8::FunctionTemplate>(ConstantAggregateZeroWrapper::New);
localTemplate->SetClassName(Nan::New("ConstantAggregateZero").ToLocalChecked());
localTemplate->InstanceTemplate()->SetInternalFieldCount(1);
localTemplate->Inherit(Nan::New(constantTemplate()));

Nan::SetMethod(localTemplate, "get", ConstantAggregateZeroWrapper::get);

functionTemplate.Reset(localTemplate);
}

return functionTemplate;
}

NAN_METHOD(ConstantAggregateZeroWrapper::New) {
if (!info.IsConstructCall()) {
return Nan::ThrowTypeError("ConstantAggregateZero constructor needs to be called with new");
}

if (!info[0]->IsExternal()) {
return Nan::ThrowTypeError("ConstantAggregateZero constructor needs to be called with: constantAggregateZero: External");
}

auto* constantAggregateZero = static_cast<llvm::ConstantAggregateZero*>(v8::External::Cast(*info[0])->Value());
auto* wrapper = new ConstantAggregateZeroWrapper { constantAggregateZero };
wrapper->Wrap(info.This());

info.GetReturnValue().Set(info.This());
}


NAN_METHOD(ConstantAggregateZeroWrapper::get) {
if (info.Length() != 1 || !TypeWrapper::isInstance(info[0])) {
return Nan::ThrowTypeError("get needs to be called with: type: Type");
}

auto* type = TypeWrapper::FromValue(info[0])->getType();
auto constantAggregateZero = llvm::ConstantAggregateZero::get(type);

info.GetReturnValue().Set(ConstantWrapper::of(constantAggregateZero));
}
25 changes: 25 additions & 0 deletions src/ir/constant-aggregate-zero.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H
#define LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H

#include <nan.h>
#include <llvm/IR/Constants.h>
#include "constant.h"

class ConstantAggregateZeroWrapper: public ConstantWrapper, public FromValueMixin<ConstantAggregateZeroWrapper> {
public:
static NAN_MODULE_INIT(Init);
static v8::Local<v8::Object> of(llvm::ConstantAggregateZero* constantAggregateZero);
using FromValueMixin<ConstantAggregateZeroWrapper>::FromValue;
llvm::ConstantAggregateZero* getConstantAggregateZero();

private:
explicit ConstantAggregateZeroWrapper(llvm::ConstantAggregateZero* constantAggregateZero) : ConstantWrapper { constantAggregateZero }
{}

static Nan::Persistent<v8::FunctionTemplate>& constantAggregateZeroTemplate();

static NAN_METHOD(New);
static NAN_METHOD(get);
};

#endif //LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H
197 changes: 197 additions & 0 deletions src/ir/constant-expr.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
#include "constant-expr.h"
#include "type.h"

NAN_MODULE_INIT(ConstantExprWrapper::Init) {
auto constantExpr = Nan::GetFunction(Nan::New(constantExprTemplate())).ToLocalChecked();

Nan::Set(target, Nan::New("ConstantExpr").ToLocalChecked(), constantExpr);
}

v8::Local<v8::Object> ConstantExprWrapper::of(llvm::ConstantExpr* constantExpr) {
auto constructor = Nan::GetFunction(Nan::New(constantExprTemplate())).ToLocalChecked();
v8::Local<v8::Value> args[1] = { Nan::New<v8::External> (constantExpr) };

auto instance = Nan::NewInstance(constructor, 1, args).ToLocalChecked();

Nan::EscapableHandleScope escapableHandleScope {};
return escapableHandleScope.Escape(instance);
}

llvm::ConstantExpr* ConstantExprWrapper::getConstantExpr() {
return static_cast<llvm::ConstantExpr*>(getValue());
}

Nan::Persistent<v8::FunctionTemplate>& ConstantExprWrapper::constantExprTemplate() {
static Nan::Persistent<v8::FunctionTemplate> functionTemplate {};

if (functionTemplate.IsEmpty()) {
v8::Local<v8::FunctionTemplate> localTemplate = Nan::New<v8::FunctionTemplate>(ConstantExprWrapper::New);
localTemplate->SetClassName(Nan::New("ConstantExpr").ToLocalChecked());
localTemplate->InstanceTemplate()->SetInternalFieldCount(1);
localTemplate->Inherit(Nan::New(constantTemplate()));

Nan::SetMethod(localTemplate, "getAlignOf", ConstantExprWrapper::getAlignOf);
Nan::SetMethod(localTemplate, "getSizeOf", ConstantExprWrapper::getSizeOf);
Nan::SetMethod(localTemplate, "getOr", ConstantExprWrapper::getOr);
Nan::SetMethod(localTemplate, "getPointerBitCastOrAddrSpaceCast", ConstantExprWrapper::getPointerBitCastOrAddrSpaceCast);
Nan::SetMethod(localTemplate, "getGetElementPtr", ConstantExprWrapper::getGetElementPtr);
Nan::SetMethod(localTemplate, "getPointerCast", ConstantExprWrapper::getPointerCast);
Nan::SetMethod(localTemplate, "getIntegerCast", ConstantExprWrapper::getIntegerCast);
Nan::SetMethod(localTemplate, "getFPCast", ConstantExprWrapper::getFPCast);
Nan::SetMethod(localTemplate, "getBitCast", ConstantExprWrapper::getBitCast);

functionTemplate.Reset(localTemplate);
}

return functionTemplate;
}

NAN_METHOD(ConstantExprWrapper::New) {
if (!info.IsConstructCall()) {
return Nan::ThrowTypeError("ConstantExpr constructor needs to be called with new");
}

if (!info[0]->IsExternal()) {
return Nan::ThrowTypeError("ConstantExpr constructor needs to be called with: constantExpr: External");
}

auto* constantExpr = static_cast<llvm::ConstantExpr*>(v8::External::Cast(*info[0])->Value());
auto* wrapper = new ConstantExprWrapper { constantExpr };
wrapper->Wrap(info.This());

info.GetReturnValue().Set(info.This());
}

NAN_METHOD(ConstantExprWrapper::getAlignOf) {
if (info.Length() != 1 || !TypeWrapper::isInstance(info[1])) {
return Nan::ThrowTypeError("getAlignOf needs to be called with: type: Type");
}

auto type = TypeWrapper::FromValue(info[0])->getType();
auto constantAlign = llvm::ConstantExpr::getAlignOf(type);

info.GetReturnValue().Set(ConstantWrapper::of(constantAlign));
}

NAN_METHOD(ConstantExprWrapper::getSizeOf) {
if (info.Length() != 1 || !TypeWrapper::isInstance(info[1])) {
return Nan::ThrowTypeError("getSizeOf needs to be called with: type: Type");
}

auto type = TypeWrapper::FromValue(info[0])->getType();
auto constantSize = llvm::ConstantExpr::getSizeOf(type);

info.GetReturnValue().Set(ConstantWrapper::of(constantSize));
}

NAN_METHOD(ConstantExprWrapper::getFPCast) {
if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1])) {
return Nan::ThrowTypeError("getFPCast needs to be called with: constant: Constant, type: Type");
}

auto constant = ConstantWrapper::FromValue(info[0])->getConstant();
auto type = TypeWrapper::FromValue(info[1])->getType();

auto constantCast = llvm::ConstantExpr::getFPCast(constant, type);

info.GetReturnValue().Set(ConstantWrapper::of(constantCast));
}

NAN_METHOD(ConstantExprWrapper::getBitCast) {
if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1])) {
return Nan::ThrowTypeError("getBitCast needs to be called with: constant: Constant, type: Type");
}

auto constant = ConstantWrapper::FromValue(info[0])->getConstant();
auto type = TypeWrapper::FromValue(info[1])->getType();

auto constantCast = llvm::ConstantExpr::getBitCast(constant, type);

info.GetReturnValue().Set(ConstantWrapper::of(constantCast));
}

NAN_METHOD(ConstantExprWrapper::getIntegerCast) {
if (info.Length() != 3 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1]) || !info[2]->IsBoolean()) {
return Nan::ThrowTypeError("getIntegerCast needs to be called with: constant: Constant, type: Type, signed: Boolean");
}

auto constant = ConstantWrapper::FromValue(info[0])->getConstant();
auto type = TypeWrapper::FromValue(info[1])->getType();
bool isSigned = Nan::To<bool>(info[3]).FromJust();

auto constantCast = llvm::ConstantExpr::getIntegerCast(constant, type, isSigned);

info.GetReturnValue().Set(ConstantWrapper::of(constantCast));
}

NAN_METHOD(ConstantExprWrapper::getGetElementPtr) {
if (info.Length() < 3 || !TypeWrapper::isInstance(info[0]) || !ConstantWrapper::isInstance(info[1]) || !info[2]->IsArray() ||
(info.Length() == 4 && !info[3]->IsBoolean())) {
return Nan::ThrowTypeError("getGetElementPtr needs to be called with type: Type, constant: Constant, idxList: Constant[], inBounds?: boolean");
}

auto* type = TypeWrapper::FromValue(info[0])->getType();
auto* ptr = ConstantWrapper::FromValue(info[1])->getConstant();
auto indexValues = v8::Array::Cast(*info[2]);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to use the toVector template from util/array for the conversion of the v8Array to a vector.

std::vector<llvm::Constant*> idxList { indexValues->Length() };

for (uint32_t i = 0; i < indexValues->Length(); ++i) {
auto idx = indexValues->Get(i);

if (!ConstantWrapper::isInstance(idx)) {
return Nan::ThrowTypeError("Constant expected for idxList element");
}

idxList[i] = ConstantWrapper::FromValue(idx)->getConstant();
}

bool inBounds = false;

if (info.Length() == 4) {
inBounds = Nan::To<bool>(info[3]).FromJust();
}

auto* gep = llvm::ConstantExpr::getGetElementPtr(type, ptr, idxList, inBounds);
info.GetReturnValue().Set(ConstantWrapper::of(gep));
}

NAN_METHOD(ConstantExprWrapper::getOr) {
if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !ConstantWrapper::isInstance(info[1])) {
return Nan::ThrowTypeError("getOr needs to be called with: constant1: Constant, constant2: Constant");
}

auto constant1 = ConstantWrapper::FromValue(info[0])->getConstant();
auto constant2 = ConstantWrapper::FromValue(info[1])->getConstant();

auto constant = llvm::ConstantExpr::getOr(constant1, constant2);

info.GetReturnValue().Set(ConstantWrapper::of(constant));
}

NAN_METHOD(ConstantExprWrapper::getPointerBitCastOrAddrSpaceCast) {
if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1])) {
return Nan::ThrowTypeError("getPointerBitCastOrAddrSpaceCast needs to be called with: constant: Constant, type: Type");
}


auto constant = ConstantWrapper::FromValue(info[0])->getConstant();
auto type = TypeWrapper::FromValue(info[1])->getType();

auto constantBitCast = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(constant, type);

info.GetReturnValue().Set(ConstantWrapper::of(constantBitCast));
}

NAN_METHOD(ConstantExprWrapper::getPointerCast) {
if (info.Length() != 2 || !ConstantWrapper::isInstance(info[0]) || !TypeWrapper::isInstance(info[1])) {
return Nan::ThrowTypeError("getPointerCast needs to be called with: constant: Constant, type: Type");
}


auto constant = ConstantWrapper::FromValue(info[0])->getConstant();
auto type = TypeWrapper::FromValue(info[1])->getType();

auto constantBitCast = llvm::ConstantExpr::getPointerCast(constant, type);

info.GetReturnValue().Set(ConstantWrapper::of(constantBitCast));
}
Loading