From 112c2b8ba053388b25ebe9b17385d0c843a1c81c Mon Sep 17 00:00:00 2001 From: Vihan Date: Thu, 1 Mar 2018 18:45:05 -0800 Subject: [PATCH 01/23] Add ConstantExpr Signed-off-by: Vihan --- llvm-node.d.ts | 6 +++ src/ir/constant-expr.cc | 99 +++++++++++++++++++++++++++++++++++++++++ src/ir/constant-expr.h | 27 +++++++++++ src/ir/ir.cc | 4 +- 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/ir/constant-expr.cc create mode 100644 src/ir/constant-expr.h diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 1a9e005..c6c091d 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -173,6 +173,12 @@ declare namespace llvm { isAllOnesValue(): boolean; } + class ConstantExpr extends Constant { + 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; diff --git a/src/ir/constant-expr.cc b/src/ir/constant-expr.cc new file mode 100644 index 0000000..29a4d7f --- /dev/null +++ b/src/ir/constant-expr.cc @@ -0,0 +1,99 @@ +#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 ConstantExprWrapper::of(llvm::ConstantExpr* constantExpr) { + auto constructor = Nan::GetFunction(Nan::New(constantExprTemplate())).ToLocalChecked(); + v8::Local args[1] = { Nan::New (constantExpr) }; + + auto instance = Nan::NewInstance(constructor, 1, args).ToLocalChecked(); + + Nan::EscapableHandleScope escapableHandleScope {}; + return escapableHandleScope.Escape(instance); +} + +llvm::ConstantExpr* ConstantExprWrapper::getConstantExpr() { + return static_cast(getValue()); +} + +Nan::Persistent& ConstantExprWrapper::constantExprTemplate() { + static Nan::Persistent functionTemplate {}; + + if (functionTemplate.IsEmpty()) { + v8::Local localTemplate = Nan::New(ConstantExprWrapper::New); + localTemplate->SetClassName(Nan::New("ConstantExpr").ToLocalChecked()); + localTemplate->InstanceTemplate()->SetInternalFieldCount(1); + localTemplate->Inherit(Nan::New(constantTemplate())); + + Nan::SetMethod(localTemplate, "getOr", ConstantExprWrapper::getOr); + Nan::SetMethod(localTemplate, "getPointerBitCastOrAddrSpaceCast", ConstantExprWrapper::getPointerBitCastOrAddrSpaceCast); + Nan::SetMethod(localTemplate, "getPointerCast", ConstantExprWrapper::getPointerCast); + + 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(v8::External::Cast(*info[0])->Value()); + auto* wrapper = new ConstantExprWrapper { constantExpr }; + wrapper->Wrap(info.This()); + + info.GetReturnValue().Set(info.This()); +} + +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)); +} diff --git a/src/ir/constant-expr.h b/src/ir/constant-expr.h new file mode 100644 index 0000000..92ba25d --- /dev/null +++ b/src/ir/constant-expr.h @@ -0,0 +1,27 @@ +#ifndef LLVM_NODE_CONSTANT_EXPR_H +#define LLVM_NODE_CONSTANT_EXPR_H + +#include +#include +#include "constant.h" + +class ConstantExprWrapper: public ConstantWrapper, public FromValueMixin { +public: + static NAN_MODULE_INIT(Init); + static v8::Local of(llvm::ConstantExpr* constantExpr); + using FromValueMixin::FromValue; + llvm::ConstantExpr* getConstantExpr(); + +private: + explicit ConstantExprWrapper(llvm::ConstantExpr* constantExpr) : ConstantWrapper { constantExpr } + {} + + static Nan::Persistent& constantExprTemplate(); + + static NAN_METHOD(New); + static NAN_METHOD(getOr); + static NAN_METHOD(getPointerBitCastOrAddrSpaceCast); + static NAN_METHOD(getPointerCast); +}; + +#endif //LLVM_NODE_CONSTANT_EXPR_H diff --git a/src/ir/ir.cc b/src/ir/ir.cc index fb01b39..b6df05a 100644 --- a/src/ir/ir.cc +++ b/src/ir/ir.cc @@ -33,6 +33,7 @@ #include "visibility-types.h" #include "attribute.h" #include "undef-value.h" +#include "constant-expr.h" NAN_MODULE_INIT(InitIR) { AllocaInstWrapper::Init(target); @@ -47,6 +48,7 @@ NAN_MODULE_INIT(InitIR) { ConstantWrapper::Init(target); ConstantArrayWrapper::Init(target); ConstantDataArrayWrapper::Init(target); + ConstantExprWrapper::Init(target); ConstantFPWrapper::Init(target); ConstantIntWrapper::Init(target); ConstantPointerNullWrapper::Init(target); @@ -66,4 +68,4 @@ NAN_MODULE_INIT(InitIR) { ValueWrapper::Init(target); InitVerifier(target); InitVisibilityTypes(target); -} \ No newline at end of file +} From b67b94b0028d1dc8eca3faab6f2a3d4caa4d24eb Mon Sep 17 00:00:00 2001 From: Vihan Date: Thu, 1 Mar 2018 19:04:00 -0800 Subject: [PATCH 02/23] Add a couple more methods Signed-off-by: Vihan --- src/ir/constant-expr.cc | 53 +++++++++++++++++++++++++++++++++++++++++ src/ir/constant-expr.h | 4 ++++ 2 files changed, 57 insertions(+) diff --git a/src/ir/constant-expr.cc b/src/ir/constant-expr.cc index 29a4d7f..124bec2 100644 --- a/src/ir/constant-expr.cc +++ b/src/ir/constant-expr.cc @@ -31,9 +31,13 @@ Nan::Persistent& ConstantExprWrapper::constantExprTemplate 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, "getPointerCast", ConstantExprWrapper::getPointerCast); + Nan::SetMethod(localTemplate, "getIntegerCast", ConstantExprWrapper::getIntegerCast); + Nan::SetMethod(localTemplate, "getFPCast", ConstantExprWrapper::getFPCast); functionTemplate.Reset(localTemplate); } @@ -57,6 +61,55 @@ NAN_METHOD(ConstantExprWrapper::New) { 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::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(info[3]).FromJust(); + + auto constantCast = llvm::ConstantExpr::getIntegerCast(constant, type, isSigned); + + info.GetReturnValue().Set(ConstantWrapper::of(constantCast)); +} + 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"); diff --git a/src/ir/constant-expr.h b/src/ir/constant-expr.h index 92ba25d..e2732e2 100644 --- a/src/ir/constant-expr.h +++ b/src/ir/constant-expr.h @@ -19,9 +19,13 @@ class ConstantExprWrapper: public ConstantWrapper, public FromValueMixin& constantExprTemplate(); static NAN_METHOD(New); + static NAN_METHOD(getAlignOf); + static NAN_METHOD(getSizeOf); static NAN_METHOD(getOr); static NAN_METHOD(getPointerBitCastOrAddrSpaceCast); static NAN_METHOD(getPointerCast); + static NAN_METHOD(getIntegerCast); + static NAN_METHOD(getFPCast); }; #endif //LLVM_NODE_CONSTANT_EXPR_H From 7547c2c33d5d94d65956031949cf273f5545d66f Mon Sep 17 00:00:00 2001 From: Vihan Date: Thu, 1 Mar 2018 19:12:49 -0800 Subject: [PATCH 03/23] Add ConstantExpr.getBitCast Signed-off-by: Vihan --- llvm-node.d.ts | 4 ++++ src/ir/constant-expr.cc | 14 ++++++++++++++ src/ir/constant-expr.h | 1 + 3 files changed, 19 insertions(+) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index c6c091d..84eab9a 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -174,8 +174,12 @@ declare namespace llvm { } 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 } diff --git a/src/ir/constant-expr.cc b/src/ir/constant-expr.cc index 124bec2..15d5ae9 100644 --- a/src/ir/constant-expr.cc +++ b/src/ir/constant-expr.cc @@ -38,6 +38,7 @@ Nan::Persistent& ConstantExprWrapper::constantExprTemplate 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); } @@ -96,6 +97,19 @@ NAN_METHOD(ConstantExprWrapper::getFPCast) { 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"); diff --git a/src/ir/constant-expr.h b/src/ir/constant-expr.h index e2732e2..c84e71f 100644 --- a/src/ir/constant-expr.h +++ b/src/ir/constant-expr.h @@ -26,6 +26,7 @@ class ConstantExprWrapper: public ConstantWrapper, public FromValueMixin Date: Tue, 6 Mar 2018 17:16:55 -0800 Subject: [PATCH 04/23] Add DataLayout.getTypeAllocSize function Adds DataLayout.getTypeAllocSize which obtains the size of a given LVLM Type as a number. Useful for passing to things like malloc() Signed-off-by: Vihan --- llvm-node.d.ts | 2 ++ src/ir/data-layout.cc | 15 +++++++++++++++ src/ir/data-layout.h | 1 + 3 files changed, 18 insertions(+) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 84eab9a..32e47bc 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -368,6 +368,8 @@ declare namespace llvm { getTypeStoreSize(type: Type): number; + getTypeAllocSize(type: Type): number; + getIntPtrType(context: LLVMContext, as: number): Type; } diff --git a/src/ir/data-layout.cc b/src/ir/data-layout.cc index c22e816..84d6ee8 100644 --- a/src/ir/data-layout.cc +++ b/src/ir/data-layout.cc @@ -27,6 +27,7 @@ NAN_MODULE_INIT(DataLayoutWrapper::Init) { Nan::SetPrototypeMethod(tpl, "getStringRepresentation", DataLayoutWrapper::getStringRepresentation); Nan::SetPrototypeMethod(tpl, "getPrefTypeAlignment", DataLayoutWrapper::getPrefTypeAlignment); Nan::SetPrototypeMethod(tpl, "getTypeStoreSize", DataLayoutWrapper::getTypeStoreSize); + Nan::SetPrototypeMethod(tpl, "getTypeAllocSize", DataLayoutWrapper::getTypeAllocSize); Nan::SetPrototypeMethod(tpl, "getPointerSize", DataLayoutWrapper::getPointerSize); Nan::SetPrototypeMethod(tpl, "getIntPtrType", DataLayoutWrapper::getIntPtrType); @@ -92,6 +93,20 @@ NAN_METHOD(DataLayoutWrapper::getTypeStoreSize) { info.GetReturnValue().Set(Nan::New(static_cast(size))); } +NAN_METHOD(DataLayoutWrapper::getTypeAllocSize) { + if (info.Length() != 1 || !TypeWrapper::isInstance(info[0])) { + return Nan::ThrowTypeError("getTypeAllocSize needs to be called with: type: Type"); + } + + auto* type = TypeWrapper::FromValue(info[0])->getType(); + auto dataLayout = DataLayoutWrapper::FromValue(info.Holder())->getDataLayout(); + + auto size = dataLayout.getTypeAllocSize(type); + assert (size < UINT32_MAX && "V8 does not support uint64 but size overflows uint32"); // v8 does not support uint64_t :( + + info.GetReturnValue().Set(Nan::New(static_cast(size))); +} + NAN_METHOD(DataLayoutWrapper::getIntPtrType) { if (info.Length() < 1 || !LLVMContextWrapper::isInstance(info[0]) || (info.Length() == 2 && !info[1]->IsUint32()) || diff --git a/src/ir/data-layout.h b/src/ir/data-layout.h index 1536784..680b3e1 100644 --- a/src/ir/data-layout.h +++ b/src/ir/data-layout.h @@ -28,6 +28,7 @@ class DataLayoutWrapper: public Nan::ObjectWrap, public FromValueMixin Date: Tue, 6 Mar 2018 17:41:58 -0800 Subject: [PATCH 05/23] Add DataLayout.getTypeAllocSizeInBits Returns type size in bits. Signed-off-by: Vihan --- llvm-node.d.ts | 2 ++ src/ir/data-layout.cc | 15 +++++++++++++++ src/ir/data-layout.h | 1 + 3 files changed, 18 insertions(+) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 32e47bc..7aae937 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -370,6 +370,8 @@ declare namespace llvm { getTypeAllocSize(type: Type): number; + getTypeAllocSizeInBits(type: Type): number; + getIntPtrType(context: LLVMContext, as: number): Type; } diff --git a/src/ir/data-layout.cc b/src/ir/data-layout.cc index 84d6ee8..f1f074b 100644 --- a/src/ir/data-layout.cc +++ b/src/ir/data-layout.cc @@ -28,6 +28,7 @@ NAN_MODULE_INIT(DataLayoutWrapper::Init) { Nan::SetPrototypeMethod(tpl, "getPrefTypeAlignment", DataLayoutWrapper::getPrefTypeAlignment); Nan::SetPrototypeMethod(tpl, "getTypeStoreSize", DataLayoutWrapper::getTypeStoreSize); Nan::SetPrototypeMethod(tpl, "getTypeAllocSize", DataLayoutWrapper::getTypeAllocSize); + Nan::SetPrototypeMethod(tpl, "getTypeAllocSizeInBits", DataLayoutWrapper::getTypeAllocSizeInBits); Nan::SetPrototypeMethod(tpl, "getPointerSize", DataLayoutWrapper::getPointerSize); Nan::SetPrototypeMethod(tpl, "getIntPtrType", DataLayoutWrapper::getIntPtrType); @@ -107,6 +108,20 @@ NAN_METHOD(DataLayoutWrapper::getTypeAllocSize) { info.GetReturnValue().Set(Nan::New(static_cast(size))); } +NAN_METHOD(DataLayoutWrapper::getTypeAllocSizeInBits) { + if (info.Length() != 1 || !TypeWrapper::isInstance(info[0])) { + return Nan::ThrowTypeError("getTypeAllocSizeInBits needs to be called with: type: Type"); + } + + auto* type = TypeWrapper::FromValue(info[0])->getType(); + auto dataLayout = DataLayoutWrapper::FromValue(info.Holder())->getDataLayout(); + + auto size = dataLayout.getTypeAllocSizeInBits(type); + assert (size < UINT32_MAX && "V8 does not support uint64 but size overflows uint32"); // v8 does not support uint64_t :( + + info.GetReturnValue().Set(Nan::New(static_cast(size))); +} + NAN_METHOD(DataLayoutWrapper::getIntPtrType) { if (info.Length() < 1 || !LLVMContextWrapper::isInstance(info[0]) || (info.Length() == 2 && !info[1]->IsUint32()) || diff --git a/src/ir/data-layout.h b/src/ir/data-layout.h index 680b3e1..27c99bc 100644 --- a/src/ir/data-layout.h +++ b/src/ir/data-layout.h @@ -29,6 +29,7 @@ class DataLayoutWrapper: public Nan::ObjectWrap, public FromValueMixin Date: Tue, 6 Mar 2018 17:59:58 -0800 Subject: [PATCH 06/23] Add IntegerType class. Signed-off-by: Vihan --- src/ir/data-layout.cc | 3 +- src/ir/integer-type.cc | 80 ++++++++++++++++++++++++++++++++++++++++++ src/ir/integer-type.h | 34 ++++++++++++++++++ src/ir/ir.cc | 2 ++ src/ir/type.cc | 4 ++- 5 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 src/ir/integer-type.cc create mode 100644 src/ir/integer-type.h diff --git a/src/ir/data-layout.cc b/src/ir/data-layout.cc index 84d6ee8..c923f5f 100644 --- a/src/ir/data-layout.cc +++ b/src/ir/data-layout.cc @@ -5,6 +5,7 @@ #include "../util/string.h" #include "data-layout.h" #include "type.h" +#include "integer-type.h" Nan::Persistent DataLayoutWrapper::functionTemplate {}; @@ -123,7 +124,7 @@ NAN_METHOD(DataLayoutWrapper::getIntPtrType) { } auto* type = dataLayout.getIntPtrType(context, addressSpace); - info.GetReturnValue().Set(TypeWrapper::of(type)); + info.GetReturnValue().Set(IntegerTypeWrapper::of(type)); } llvm::DataLayout DataLayoutWrapper::getDataLayout() { diff --git a/src/ir/integer-type.cc b/src/ir/integer-type.cc new file mode 100644 index 0000000..c2a07b2 --- /dev/null +++ b/src/ir/integer-type.cc @@ -0,0 +1,80 @@ +#include "integer-type.h" + +NAN_MODULE_INIT(IntegerTypeWrapper::Init) { + auto integerType = Nan::GetFunction(Nan::New(integerTypeTemplate())).ToLocalChecked(); + Nan::Set(target, Nan::New("IntegerType").ToLocalChecked(), integerType); +} + +NAN_METHOD(IntegerTypeWrapper::New) { + if (!info.IsConstructCall()) { + return Nan::ThrowTypeError("Constructor needs to be called with new"); + } + + if (info.Length() < 1 || !info[0]->IsExternal()) { + return Nan::ThrowTypeError("Expected pointer type pointer"); + } + + auto* type = static_cast(v8::External::Cast(*info[0])->Value()); + auto* wrapper = new IntegerTypeWrapper { type }; + wrapper->Wrap(info.This()); + + info.GetReturnValue().Set(info.This()); +} + +NAN_METHOD(IntegerTypeWrapper::get) { + if (info.Length() != 2 || !LLVMContextWrapper::isInstance(info[0]) || !info[1]->IsUint32()) { + return Nan::ThrowTypeError("IntegerTypeWrapper.get needs to be called with: context: LLVMContext, bitWidth: uint32"); + } + + auto& context = LLVMContextWrapper::FromValue(info[0])->getContext(); + uint32_t bitWidth = Nan::To(info[1]).FromJust(); + + auto* integerType = llvm::IntegerType::get(context, bitWidth); + + info.GetReturnValue().Set(IntegerTypeWrapper::of(integerType)); +} + +NAN_GETTER(IntegerTypeWrapper::getBitWidth) { + auto* integerType = IntegerTypeWrapper::FromValue(info.Holder())->getIntegerType(); + uint32_t bitWidth = integerType->getBitWidth(); + + info.GetReturnValue().Set(Nan::New(bitWidth)); +} + +v8::Local IntegerTypeWrapper::of(llvm::IntegerType *type) { + Nan::EscapableHandleScope escapeScope {}; + + v8::Local functionTemplate = Nan::New(integerTypeTemplate()); + auto constructorFunction = Nan::GetFunction(functionTemplate).ToLocalChecked(); + v8::Local argv[1] = { Nan::New(type) }; + v8::Local object = Nan::NewInstance(constructorFunction, 1, argv).ToLocalChecked(); + + return escapeScope.Escape(object); +} + +Nan::Persistent& IntegerTypeWrapper::integerTypeTemplate() { + static Nan::Persistent persistentTemplate {}; + + if (persistentTemplate.IsEmpty()) { + v8::Local integerTypeTemplate = Nan::New(IntegerTypeWrapper::New); + + Nan::SetMethod(integerTypeTemplate, "get", IntegerTypeWrapper::get); + integerTypeTemplate->SetClassName(Nan::New("IntegerType").ToLocalChecked()); + integerTypeTemplate->InstanceTemplate()->SetInternalFieldCount(1); + integerTypeTemplate->Inherit(Nan::New(typeTemplate())); + + Nan::SetAccessor(integerTypeTemplate->InstanceTemplate(), Nan::New("bitWidth").ToLocalChecked(), IntegerTypeWrapper::getBitWidth); + + persistentTemplate.Reset(integerTypeTemplate); + } + + return persistentTemplate; +} + +bool IntegerTypeWrapper::isInstance(v8::Local object) { + return Nan::New(integerTypeTemplate())->HasInstance(object); +} + +llvm::IntegerType *IntegerTypeWrapper::getIntegerType() { + return static_cast(getType()); +} diff --git a/src/ir/integer-type.h b/src/ir/integer-type.h new file mode 100644 index 0000000..6c889be --- /dev/null +++ b/src/ir/integer-type.h @@ -0,0 +1,34 @@ +#ifndef LLVM_NODE_INTEGER_TYPE_H +#define LLVM_NODE_INTEGER_TYPE_H + +#include +#include +#include +#include "llvm-context.h" +#include "../util/from-value-mixin.h" +#include "type.h" + +class IntegerTypeWrapper: public TypeWrapper, public FromValueMixin { +public: + static NAN_MODULE_INIT(Init); + static v8::Local of(llvm::IntegerType *type); + using FromValueMixin::FromValue; + + llvm::IntegerType* getIntegerType(); + static bool isInstance(v8::Local value); + +protected: + llvm::Type* type; + explicit IntegerTypeWrapper(llvm::IntegerType* type) : TypeWrapper { type } { + } + + static Nan::Persistent& integerTypeTemplate(); + +private: + // Static Methods + static NAN_METHOD(New); + static NAN_METHOD(get); + static NAN_GETTER(getBitWidth); +}; + +#endif //LLVM_NODE_INTEGER_TYPE_H diff --git a/src/ir/ir.cc b/src/ir/ir.cc index b6df05a..c5b5018 100644 --- a/src/ir/ir.cc +++ b/src/ir/ir.cc @@ -34,6 +34,7 @@ #include "attribute.h" #include "undef-value.h" #include "constant-expr.h" +#include "integer-type.h" NAN_MODULE_INIT(InitIR) { AllocaInstWrapper::Init(target); @@ -58,6 +59,7 @@ NAN_MODULE_INIT(InitIR) { GlobalVariableWrapper::Init(target); IRBuilderWrapper::Init(target); InitLinkageTypes(target); + IntegerTypeWrapper::Init(target); ModuleWrapper::Init(target); LLVMContextWrapper::Init(target); PhiNodeWrapper::Init(target); diff --git a/src/ir/type.cc b/src/ir/type.cc index 1ebc0f1..a926809 100644 --- a/src/ir/type.cc +++ b/src/ir/type.cc @@ -9,6 +9,7 @@ #include "pointer-type.h" #include "array-type.h" #include "struct-type.h" +#include "integer-type.h" NAN_MODULE_INIT(TypeWrapper::Init) { auto type = Nan::GetFunction(Nan::New(typeTemplate())).ToLocalChecked(); @@ -149,6 +150,8 @@ v8::Local TypeWrapper::of(llvm::Type *type) { result = ArrayTypeWrapper::of(static_cast(type)); } else if (type->isStructTy()) { result = StructTypeWrapper::of(static_cast(type)); + } else if (type->isIntegerTy()) { + result = IntegerTypeWrapper::of(static_cast(type)); } else { v8::Local functionTemplate = Nan::New(typeTemplate()); auto constructorFunction = Nan::GetFunction(functionTemplate).ToLocalChecked(); @@ -253,4 +256,3 @@ bool TypeWrapper::isInstance(v8::Local object) { llvm::Type *TypeWrapper::getType() { return type; } - From 894dbf265744b2327942ee700640e2bb09d2433e Mon Sep 17 00:00:00 2001 From: Vihan Date: Wed, 7 Mar 2018 20:30:48 -0800 Subject: [PATCH 07/23] Add ConstantAggregateZero class Signed-off-by: Vihan --- llvm-node.d.ts | 6 +++ src/ir/constant-aggregate-zero.cc | 67 +++++++++++++++++++++++++++++++ src/ir/constant-aggregate-zero.h | 25 ++++++++++++ src/ir/constant.cc | 5 ++- src/ir/ir.cc | 1 + 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/ir/constant-aggregate-zero.cc create mode 100644 src/ir/constant-aggregate-zero.h diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 7aae937..5b433ed 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -173,6 +173,12 @@ 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 diff --git a/src/ir/constant-aggregate-zero.cc b/src/ir/constant-aggregate-zero.cc new file mode 100644 index 0000000..8a41735 --- /dev/null +++ b/src/ir/constant-aggregate-zero.cc @@ -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 ConstantAggregateZeroWrapper::of(llvm::ConstantAggregateZero* constantAggregateZero) { + auto constructor = Nan::GetFunction(Nan::New(constantAggregateZeroTemplate())).ToLocalChecked(); + v8::Local args[1] = { Nan::New (constantAggregateZero) }; + + auto instance = Nan::NewInstance(constructor, 1, args).ToLocalChecked(); + + Nan::EscapableHandleScope escapableHandleScope {}; + return escapableHandleScope.Escape(instance); +} + +llvm::ConstantAggregateZero* ConstantAggregateZeroWrapper::getConstantAggregateZero() { + return static_cast(getValue()); +} + +Nan::Persistent& ConstantAggregateZeroWrapper::constantAggregateZeroTemplate() { + static Nan::Persistent functionTemplate {}; + + if (functionTemplate.IsEmpty()) { + v8::Local localTemplate = Nan::New(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(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() != 2 || !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)); +} diff --git a/src/ir/constant-aggregate-zero.h b/src/ir/constant-aggregate-zero.h new file mode 100644 index 0000000..a9bda14 --- /dev/null +++ b/src/ir/constant-aggregate-zero.h @@ -0,0 +1,25 @@ +#ifndef LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H +#define LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H + +#include +#include +#include "constant.h" + +class ConstantAggregateZeroWrapper: public ConstantWrapper, public FromValueMixin { +public: + static NAN_MODULE_INIT(Init); + static v8::Local of(llvm::ConstantAggregateZero* constantAggregateZero); + using FromValueMixin::FromValue; + llvm::ConstantAggregateZero* getConstantAggregateZero(); + +private: + explicit ConstantAggregateZeroWrapper(llvm::ConstantAggregateZero* constantAggregateZero) : ConstantWrapper { constantAggregateZero } + {} + + static Nan::Persistent& constantAggregateZeroTemplate(); + + static NAN_METHOD(New); + static NAN_METHOD(get); +}; + +#endif //LLVM_NODE_CONSTANT_AGGREGATE_ZERO_H diff --git a/src/ir/constant.cc b/src/ir/constant.cc index 2d8aa28..ae2d550 100644 --- a/src/ir/constant.cc +++ b/src/ir/constant.cc @@ -13,6 +13,7 @@ #include "constant-int.h" #include "constant-data-array.h" #include "constant-pointer-null.h" +#include "constant-aggregate-zero.h" #include "global-variable.h" #include "constant-struct.h" #include "constant-array.h" @@ -42,6 +43,8 @@ v8::Local ConstantWrapper::of(llvm::Constant *constant) { result = ConstantStructWrapper::of(static_cast(constant)); } else if (llvm::ConstantArray::classof(constant)) { result = ConstantArrayWrapper::of(static_cast(constant)); + } else if (llvm::ConstantAggregateZero::classof(constant)) { + result = ConstantAggregateZeroWrapper::of(static_cast(constant)); } else if (llvm::UndefValue::classof(constant)) { result = UndefValueWrapper::of(static_cast(constant)); } else { @@ -130,4 +133,4 @@ Nan::Persistent& ConstantWrapper::constantTemplate() { llvm::Constant *ConstantWrapper::getConstant() { return static_cast(getValue()); -} \ No newline at end of file +} diff --git a/src/ir/ir.cc b/src/ir/ir.cc index c5b5018..b1e63d9 100644 --- a/src/ir/ir.cc +++ b/src/ir/ir.cc @@ -31,6 +31,7 @@ #include "constant-struct.h" #include "constant-array.h" #include "visibility-types.h" +#include "constant-aggregate-zero.h" #include "attribute.h" #include "undef-value.h" #include "constant-expr.h" From 5c215c564b823da8e8071fe0363f9a473bd65397 Mon Sep 17 00:00:00 2001 From: Vihan Date: Wed, 7 Mar 2018 20:33:05 -0800 Subject: [PATCH 08/23] Add missing to IR Signed-off-by: Vihan --- src/ir/constant-aggregate-zero.cc | 2 +- src/ir/ir.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ir/constant-aggregate-zero.cc b/src/ir/constant-aggregate-zero.cc index 8a41735..d0eed42 100644 --- a/src/ir/constant-aggregate-zero.cc +++ b/src/ir/constant-aggregate-zero.cc @@ -56,7 +56,7 @@ NAN_METHOD(ConstantAggregateZeroWrapper::New) { NAN_METHOD(ConstantAggregateZeroWrapper::get) { - if (info.Length() != 2 || !TypeWrapper::isInstance(info[0])) { + if (info.Length() != 1 || !TypeWrapper::isInstance(info[0])) { return Nan::ThrowTypeError("get needs to be called with: type: Type"); } diff --git a/src/ir/ir.cc b/src/ir/ir.cc index b1e63d9..840d970 100644 --- a/src/ir/ir.cc +++ b/src/ir/ir.cc @@ -49,6 +49,7 @@ NAN_MODULE_INIT(InitIR) { CallInstWrapper::Init(target); ConstantWrapper::Init(target); ConstantArrayWrapper::Init(target); + ConstantAggregateZeroWrapper::Init(target); ConstantDataArrayWrapper::Init(target); ConstantExprWrapper::Init(target); ConstantFPWrapper::Init(target); From e0665186b18d31fcb672c3d8baf9f76d07c93c26 Mon Sep 17 00:00:00 2001 From: Vihan Date: Sun, 11 Mar 2018 13:40:10 -0700 Subject: [PATCH 09/23] Add GEP for ConstantExpr Signed-off-by: Vihan --- src/ir/constant-expr.cc | 33 ++++++++++++++++++++++++++++++++- src/ir/constant-expr.h | 1 + 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/ir/constant-expr.cc b/src/ir/constant-expr.cc index 15d5ae9..72850ad 100644 --- a/src/ir/constant-expr.cc +++ b/src/ir/constant-expr.cc @@ -1,7 +1,6 @@ #include "constant-expr.h" #include "type.h" - NAN_MODULE_INIT(ConstantExprWrapper::Init) { auto constantExpr = Nan::GetFunction(Nan::New(constantExprTemplate())).ToLocalChecked(); @@ -35,6 +34,7 @@ Nan::Persistent& ConstantExprWrapper::constantExprTemplate 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); @@ -124,6 +124,37 @@ NAN_METHOD(ConstantExprWrapper::getIntegerCast) { 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: Value[], inBounds?: boolean"); + } + + auto* type = TypeWrapper::FromValue(info[0])->getType(); + auto* ptr = ConstantWrapper::FromValue(info[1])->getConstant(); + auto indexValues = v8::Array::Cast(*info[2]); + std::vector idxList { indexValues->Length() }; + + for (uint32_t i = 0; i < indexValues->Length(); ++i) { + auto idx = indexValues->Get(i); + + if (!ValueWrapper::isInstance(idx)) { + return Nan::ThrowTypeError("Value expected for idxList element"); + } + + idxList[i] = ValueWrapper::FromValue(idx)->getValue(); + } + + bool inBounds = false; + + if (info.Length() == 4) { + inBounds = Nan::To(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"); diff --git a/src/ir/constant-expr.h b/src/ir/constant-expr.h index c84e71f..8ea0453 100644 --- a/src/ir/constant-expr.h +++ b/src/ir/constant-expr.h @@ -23,6 +23,7 @@ class ConstantExprWrapper: public ConstantWrapper, public FromValueMixin Date: Sun, 11 Mar 2018 14:04:37 -0700 Subject: [PATCH 10/23] Use constant GEP. Signed-off-by: Vihan --- src/ir/constant-expr.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ir/constant-expr.cc b/src/ir/constant-expr.cc index 72850ad..86e24e0 100644 --- a/src/ir/constant-expr.cc +++ b/src/ir/constant-expr.cc @@ -127,22 +127,22 @@ NAN_METHOD(ConstantExprWrapper::getIntegerCast) { 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: Value[], inBounds?: boolean"); + 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]); - std::vector idxList { indexValues->Length() }; + std::vector idxList { indexValues->Length() }; for (uint32_t i = 0; i < indexValues->Length(); ++i) { auto idx = indexValues->Get(i); - if (!ValueWrapper::isInstance(idx)) { - return Nan::ThrowTypeError("Value expected for idxList element"); + if (!ConstantWrapper::isInstance(idx)) { + return Nan::ThrowTypeError("Constant expected for idxList element"); } - idxList[i] = ValueWrapper::FromValue(idx)->getValue(); + idxList[i] = ConstantWrapper::FromValue(idx)->getConstant(); } bool inBounds = false; From 366bb2e17d00f008f2f21aecc368c15136dec432 Mon Sep 17 00:00:00 2001 From: Vihan Date: Wed, 21 Mar 2018 19:46:40 -0700 Subject: [PATCH 11/23] Add IsNull call Signed-off-by: Vihan --- llvm-node.d.ts | 2 ++ src/ir/ir-builder.cc | 20 ++++++++++++++++++++ src/ir/ir-builder.h | 1 + 3 files changed, 23 insertions(+) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 5b433ed..6b8491f 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -608,6 +608,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; diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index 20df42a..9b537e6 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -113,6 +113,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createICmpUGT", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateICmpUGT>>); Nan::SetPrototypeMethod(functionTemplate, "createICmpULT", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateICmpULT>>); Nan::SetPrototypeMethod(functionTemplate, "createICmpULE", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateICmpULE>>); + Nan::SetPrototypeMethod(functionTemplate, "createIsNull", IRBuilderWrapper::CreateIsNull); Nan::SetPrototypeMethod(functionTemplate, "createLoad", IRBuilderWrapper::CreateLoad); Nan::SetPrototypeMethod(functionTemplate, "createLShr", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateLShr>>); Nan::SetPrototypeMethod(functionTemplate, "createMul", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateMul>>); @@ -394,6 +395,25 @@ NAN_METHOD(IRBuilderWrapper::CreateIntCast) { info.GetReturnValue().Set(ValueWrapper::of(casted)); } +NAN_METHOD(IRBuilderWrapper::CreateIsNull) { + if (info.Length() < 1 || !ValueWrapper::isInstance(info[0]) + || (info.Length() > 1 && !(info[1]->IsString() || info[1]->IsUndefined())) + || info.Length() > 2) { + return Nan::ThrowTypeError("createIsNull needs to be called with: value: Value, name?: string"); + } + + auto* value = ValueWrapper::FromValue(info[0])->getValue(); + std::string name {}; + + if (info.Length() > 1 && !info[1]->IsUndefined()) { + name = ToString(Nan::To(info[1]).ToLocalChecked()); + } + + auto& irBuilder = IRBuilderWrapper::FromValue(info.Holder())->irBuilder; + auto* inst = irBuilder.CreateIsNull(value, name); + info.GetReturnValue().Set(ValueWrapper::of(inst)); +} + NAN_METHOD(IRBuilderWrapper::CreateLoad) { if (info.Length() < 1 || !ValueWrapper::isInstance(info[0]) || (info.Length() > 1 && !(info[1]->IsString() || info[1]->IsUndefined())) diff --git a/src/ir/ir-builder.h b/src/ir/ir-builder.h index 4790bdd..30fbbbd 100644 --- a/src/ir/ir-builder.h +++ b/src/ir/ir-builder.h @@ -46,6 +46,7 @@ class IRBuilderWrapper: public Nan::ObjectWrap, public FromValueMixin Date: Mon, 26 Mar 2018 20:02:15 -0700 Subject: [PATCH 12/23] Add unsigned remainder to IR builder Signed-off-by: Vihan --- llvm-node.d.ts | 2 ++ src/ir/ir-builder.cc | 1 + src/llvm-node.cc | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 6b8491f..94ce5f4 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -648,6 +648,8 @@ declare namespace llvm { createSRem(lhs: Value, rhs: Value, name?: string): Value; + createURem(lhs: Value, rhs: Value, name?: string): Value; + createZExt(value: Value, destType: Type, name?: string): Value; getInsertBlock(): BasicBlock; diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index 9b537e6..bc23031 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -131,6 +131,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createSub", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSub>>); Nan::SetPrototypeMethod(functionTemplate, "createSRem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSRem>>); Nan::SetPrototypeMethod(functionTemplate, "createSIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateSIToFP>); + Nan::SetPrototypeMethod(functionTemplate, "createURem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateURem>>); Nan::SetPrototypeMethod(functionTemplate, "createUIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateUIToFP>); Nan::SetPrototypeMethod(functionTemplate, "createStore", IRBuilderWrapper::CreateStore); Nan::SetPrototypeMethod(functionTemplate, "createZExt", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateZExt>); diff --git a/src/llvm-node.cc b/src/llvm-node.cc index bc7c36c..943955c 100644 --- a/src/llvm-node.cc +++ b/src/llvm-node.cc @@ -14,4 +14,4 @@ NAN_MODULE_INIT(InitAll) { InitTarget(target); } -NODE_MODULE(llvm, InitAll) \ No newline at end of file +NODE_MODULE(llvm, InitAll) From eac80517cfaef7692663deb09f8269736d6f14a2 Mon Sep 17 00:00:00 2001 From: Vihan Date: Mon, 2 Apr 2018 22:38:09 -0700 Subject: [PATCH 13/23] Add casting functions Signed-off-by: Vihan --- llvm-node.d.ts | 8 ++++++++ src/ir/ir-builder.cc | 3 +++ src/ir/type.cc | 1 + 3 files changed, 12 insertions(+) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 94ce5f4..2c79c8a 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -451,12 +451,15 @@ declare namespace llvm { isArrayTy(): boolean; + isFloatingPointTy(): boolean; + isPointerTy(): this is PointerType; getPointerTo(addressSpace?: number): PointerType; getPrimitiveSizeInBits(): number; + toString(): string; } @@ -576,6 +579,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; @@ -652,6 +656,10 @@ declare namespace llvm { 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; } diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index bc23031..ccaf102 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -96,6 +96,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createFMul", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFMul>>); Nan::SetPrototypeMethod(functionTemplate, "createFNeg", IRBuilderWrapper::CreateFNeg); Nan::SetPrototypeMethod(functionTemplate, "createFPToSI", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateFPToSI>); + Nan::SetPrototypeMethod(functionTemplate, "createFPToUI", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateFPToUI>); Nan::SetPrototypeMethod(functionTemplate, "createFRem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFRem>>); Nan::SetPrototypeMethod(functionTemplate, "createFSub", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFSub>>); Nan::SetPrototypeMethod(functionTemplate, "createGlobalString", IRBuilderWrapper::CreateGlobalString); @@ -135,6 +136,8 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createUIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateUIToFP>); Nan::SetPrototypeMethod(functionTemplate, "createStore", IRBuilderWrapper::CreateStore); Nan::SetPrototypeMethod(functionTemplate, "createZExt", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateZExt>); + Nan::SetPrototypeMethod(functionTemplate, "createZExtOrTrunc", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateZExtOrTrunc>); + Nan::SetPrototypeMethod(functionTemplate, "createSExtOrTrunc", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateSExtOrTrunc>); Nan::SetPrototypeMethod(functionTemplate, "getInsertBlock", IRBuilderWrapper::GetInsertBlock); Nan::SetPrototypeMethod(functionTemplate, "setInsertionPoint", IRBuilderWrapper::SetInsertionPoint); diff --git a/src/ir/type.cc b/src/ir/type.cc index a926809..a41d1fb 100644 --- a/src/ir/type.cc +++ b/src/ir/type.cc @@ -238,6 +238,7 @@ Nan::Persistent& TypeWrapper::typeTemplate() { Nan::SetPrototypeMethod(typeTemplate, "isStructTy", &isOfType<&llvm::Type::isStructTy>); Nan::SetPrototypeMethod(typeTemplate, "isArrayTy", &isOfType<&llvm::Type::isArrayTy>); Nan::SetPrototypeMethod(typeTemplate, "isPointerTy", &isOfType<&llvm::Type::isPointerTy>); + Nan::SetPrototypeMethod(typeTemplate, "isFloatingPointTy", &isOfType<&llvm::Type::isFloatingPointTy>); Nan::SetAccessor(typeTemplate->InstanceTemplate(), Nan::New("typeID").ToLocalChecked(), TypeWrapper::getTypeID); Nan::SetPrototypeMethod(typeTemplate, "getPointerTo", TypeWrapper::getPointerTo); Nan::SetPrototypeMethod(typeTemplate, "getPrimitiveSizeInBits", TypeWrapper::getPrimitiveSizeInBits); From 75ebf64fc5e9300cc5e4256127b37e3a10f18d1c Mon Sep 17 00:00:00 2001 From: Vihan Date: Fri, 7 Dec 2018 17:15:05 -0800 Subject: [PATCH 14/23] Add createIntToPtr and also address review comments Signed-off-by: Vihan --- llvm-node.d.ts | 20 +++++++++++++++----- src/ir/constant.cc | 3 +++ src/ir/ir-builder.cc | 1 + 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 348a5a3..3858551 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -180,13 +180,23 @@ declare namespace llvm { } class ConstantExpr extends Constant { - static getBitCast(constant: Constant, type: Type): ConstantExpr + static getPointerCast(constant: Constant, type: Type): Constant; - static getOr(constant1: Constant, constant2: Constant): ConstantExpr + static getIntegerCast(constant: Constant, type: Type): Constant; - static getPointerBitCastOrAddrSpaceCast(constant: Constant, type: Type): ConstantExpr + static getFPCast(constant: Constant, type: Type): Constant; - static getPointerCast(constant: Constant, type: Type): ConstantExpr + static getBitCast(constant: Constant, type: Type): Constant; + + static getGetElementPtr(type: Type, constant: Constant, idxList: Constant[], inBounds?: boolean): Constant; + + static getOr(constant1: Constant, constant2: Constant): Constant; + + static getPointerBitCastOrAddrSpaceCast(constant: Constant, type: Type): Constant; + + static getAlignOf(type: Type): Constant; + + static getSizeOf(type: Type): Constant; } class ConstantFP extends Constant { @@ -384,7 +394,7 @@ declare namespace llvm { getTypeAllocSizeInBits(type: Type): number; - getIntPtrType(context: LLVMContext, as: number): Type; + getIntPtrType(context: LLVMContext, as: number): IntegerType; } class Type { diff --git a/src/ir/constant.cc b/src/ir/constant.cc index ae2d550..5be4194 100644 --- a/src/ir/constant.cc +++ b/src/ir/constant.cc @@ -17,6 +17,7 @@ #include "global-variable.h" #include "constant-struct.h" #include "constant-array.h" +#include "constant-expr.h" #include "undef-value.h" NAN_MODULE_INIT(ConstantWrapper::Init) { @@ -47,6 +48,8 @@ v8::Local ConstantWrapper::of(llvm::Constant *constant) { result = ConstantAggregateZeroWrapper::of(static_cast(constant)); } else if (llvm::UndefValue::classof(constant)) { result = UndefValueWrapper::of(static_cast(constant)); + } else if (llvm::ConstantExpr::classof(constant)) { + result = ConstantExprWrapper::of(static_cast(constant)); } else { auto constructorFunction = Nan::GetFunction(Nan::New(constantTemplate())).ToLocalChecked(); v8::Local argv[1] = { Nan::New(constant) }; diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index eafb2fa..db87ed6 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -123,6 +123,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createOr", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateOr>>); Nan::SetPrototypeMethod(functionTemplate, "createXor", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateXor>>); Nan::SetPrototypeMethod(functionTemplate, "createPhi", IRBuilderWrapper::CreatePhi); + Nan::SetPrototypeMethod(functionTemplate, "createIntToPtr", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateIntToPtr>); Nan::SetPrototypeMethod(functionTemplate, "createPtrToInt", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreatePtrToInt>); Nan::SetPrototypeMethod(functionTemplate, "createRet", IRBuilderWrapper::CreateRet); Nan::SetPrototypeMethod(functionTemplate, "createRetVoid", IRBuilderWrapper::CreateRetVoid); From 170fc44e60e581b1a1bbcfb6be081c00bd1ceba3 Mon Sep 17 00:00:00 2001 From: Vihan Date: Tue, 11 Dec 2018 17:06:44 -0800 Subject: [PATCH 15/23] Fix tests and also add last method forgot to put Signed-off-by: Vihan --- llvm-node.d.ts | 2 ++ test/ir/constant-int.spec.ts | 6 +++--- test/ir/ir-builder.spec.ts | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 93b4723..7099de3 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -665,6 +665,8 @@ declare namespace llvm { createPtrToInt(value: Value, destType: Type, name?: string): Value; + createIntToPtr(value: Value, destType: Type, name?: string): Value; + createRet(value: Value): Value; createRetVoid(): Value; diff --git a/test/ir/constant-int.spec.ts b/test/ir/constant-int.spec.ts index 9298052..9dcce53 100644 --- a/test/ir/constant-int.spec.ts +++ b/test/ir/constant-int.spec.ts @@ -28,7 +28,7 @@ describe("ir/constant-int", () => { it("returns the true value", () => { const trueValue = llvm.ConstantInt.getTrue(context); - expect(trueValue.type).toEqual(llvm.Type.getInt8Ty(context)); + expect(trueValue.type).toEqual(llvm.Type.getInt1Ty(context)); expect(trueValue.value).toBeDefined(); }); }); @@ -37,8 +37,8 @@ describe("ir/constant-int", () => { it("returns the false value", () => { const trueValue = llvm.ConstantInt.getFalse(context); - expect(trueValue.type).toEqual(llvm.Type.getInt8Ty(context)); + expect(trueValue.type).toEqual(llvm.Type.getInt1Ty(context)); expect(trueValue.value).toBe(0); }); }); -}); \ No newline at end of file +}); diff --git a/test/ir/ir-builder.spec.ts b/test/ir/ir-builder.spec.ts index 15a958c..bc1b06e 100644 --- a/test/ir/ir-builder.spec.ts +++ b/test/ir/ir-builder.spec.ts @@ -790,10 +790,10 @@ describe("IRBuilder", () => { expect(rem).toEqual(llvm.ConstantInt.get(context, 1)); }); - test("CreateURem", () => { + test("createURem", () => { const { builder, context } = createBuilderWithBlock(); - const rem = builder.CreateURem( + const rem = builder.createURem( llvm.ConstantInt.get(context, 11), llvm.ConstantInt.get(context, 2) ); From cac32ed381294c437c0ebdfb89db55c5b0b18368 Mon Sep 17 00:00:00 2001 From: Vihan Date: Tue, 11 Dec 2018 17:19:57 -0800 Subject: [PATCH 16/23] Add missing udiv Signed-off-by: Vihan --- llvm-node.d.ts | 2 ++ src/ir/ir-builder.cc | 1 + test/ir/ir-builder.spec.ts | 12 ++++++++++++ 3 files changed, 15 insertions(+) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 7099de3..7509b7c 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -687,6 +687,8 @@ declare namespace llvm { createSRem(lhs: Value, rhs: Value, name?: string): Value; + createUDiv(lhs: Value, rhs: Value, name?: string): Value; + createURem(lhs: Value, rhs: Value, name?: string): Value; createZExt(value: Value, destType: Type, name?: string): Value; diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index db87ed6..5c131df 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -133,6 +133,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createSub", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSub>>); Nan::SetPrototypeMethod(functionTemplate, "createSRem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSRem>>); Nan::SetPrototypeMethod(functionTemplate, "createSIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateSIToFP>); + Nan::SetPrototypeMethod(functionTemplate, "createUDiv", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSDiv>>); Nan::SetPrototypeMethod(functionTemplate, "createURem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateURem>>); Nan::SetPrototypeMethod(functionTemplate, "createUIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateUIToFP>); Nan::SetPrototypeMethod(functionTemplate, "createStore", IRBuilderWrapper::CreateStore); diff --git a/test/ir/ir-builder.spec.ts b/test/ir/ir-builder.spec.ts index bc1b06e..b7097cf 100644 --- a/test/ir/ir-builder.spec.ts +++ b/test/ir/ir-builder.spec.ts @@ -790,6 +790,18 @@ describe("IRBuilder", () => { expect(rem).toEqual(llvm.ConstantInt.get(context, 1)); }); + test("createUDiv", () => { + const { builder, context } = createBuilderWithBlock(); + + const div = builder.createUDiv( + llvm.ConstantInt.get(context, -1, 32, false), + llvm.ConstantInt.get(context, 2, 32) + ); + + expect(div).toBeInstanceOf(llvm.Value); + expect(div).toEqual(llvm.ConstantInt.get(context, 1073741824, 32)); + }); + test("createURem", () => { const { builder, context } = createBuilderWithBlock(); From 33eacb76e9143391b08e4f29e8e736ff46d98765 Mon Sep 17 00:00:00 2001 From: Vihan Date: Tue, 11 Dec 2018 17:24:29 -0800 Subject: [PATCH 17/23] Oops Signed-off-by: Vihan --- src/ir/ir-builder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index 5c131df..ee45bd3 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -133,7 +133,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createSub", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSub>>); Nan::SetPrototypeMethod(functionTemplate, "createSRem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSRem>>); Nan::SetPrototypeMethod(functionTemplate, "createSIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateSIToFP>); - Nan::SetPrototypeMethod(functionTemplate, "createUDiv", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateSDiv>>); + Nan::SetPrototypeMethod(functionTemplate, "createUDiv", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateUDiv>>); Nan::SetPrototypeMethod(functionTemplate, "createURem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateURem>>); Nan::SetPrototypeMethod(functionTemplate, "createUIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateUIToFP>); Nan::SetPrototypeMethod(functionTemplate, "createStore", IRBuilderWrapper::CreateStore); From 46907475297f6363c78909a6e984641e28638d30 Mon Sep 17 00:00:00 2001 From: Vihan Date: Fri, 21 Dec 2018 11:52:13 -0800 Subject: [PATCH 18/23] Fix IRBuilder tests, not sure why they were this way. Signed-off-by: Vihan --- test/ir/ir-builder.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ir/ir-builder.spec.ts b/test/ir/ir-builder.spec.ts index b7097cf..b11b56e 100644 --- a/test/ir/ir-builder.spec.ts +++ b/test/ir/ir-builder.spec.ts @@ -88,7 +88,7 @@ describe("IRBuilder", () => { expect(cast).toBeInstanceOf(llvm.Value); expect(cast.type).toEqual( - llvm.PointerType.get(llvm.Type.getInt32Ty(context), 0) + llvm.Type.getInt8PtrTy(context) ); }); @@ -799,7 +799,7 @@ describe("IRBuilder", () => { ); expect(div).toBeInstanceOf(llvm.Value); - expect(div).toEqual(llvm.ConstantInt.get(context, 1073741824, 32)); + expect(div).toEqual(llvm.ConstantInt.get(context, 2147483647, 32)); }); test("createURem", () => { From b45fd26fbbee54876862a489eedbce8c703fd071 Mon Sep 17 00:00:00 2001 From: Vihan Date: Fri, 21 Dec 2018 12:02:05 -0800 Subject: [PATCH 19/23] .bitWidth -> .getBitWidth() and other test fixes Signed-off-by: Vihan --- src/ir/integer-type.cc | 8 ++++---- src/ir/integer-type.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ir/integer-type.cc b/src/ir/integer-type.cc index e229b5c..b25ff5b 100644 --- a/src/ir/integer-type.cc +++ b/src/ir/integer-type.cc @@ -28,16 +28,16 @@ NAN_METHOD(IntegerTypeWrapper::get) { } auto& context = LLVMContextWrapper::FromValue(info[0])->getContext(); - uint32_t bitWidth = Nan::To(info[1]).FromJust(); + unsigned bitWidth = Nan::To(info[1]).FromJust(); auto* integerType = llvm::IntegerType::get(context, bitWidth); info.GetReturnValue().Set(IntegerTypeWrapper::of(integerType)); } -NAN_GETTER(IntegerTypeWrapper::getBitWidth) { +NAN_METHOD(IntegerTypeWrapper::getBitWidth) { auto* integerType = IntegerTypeWrapper::FromValue(info.Holder())->getIntegerType(); - uint32_t bitWidth = integerType->getBitWidth(); + unsigned bitWidth = integerType->getBitWidth(); info.GetReturnValue().Set(Nan::New(bitWidth)); } @@ -64,7 +64,7 @@ Nan::Persistent& IntegerTypeWrapper::integerTypeTemplate() integerTypeTemplate->InstanceTemplate()->SetInternalFieldCount(1); integerTypeTemplate->Inherit(Nan::New(typeTemplate())); - Nan::SetAccessor(integerTypeTemplate->InstanceTemplate(), Nan::New("bitWidth").ToLocalChecked(), IntegerTypeWrapper::getBitWidth); + Nan::SetPrototypeMethod(integerTypeTemplate, "getBitWidth", IntegerTypeWrapper::getBitWidth); persistentTemplate.Reset(integerTypeTemplate); } diff --git a/src/ir/integer-type.h b/src/ir/integer-type.h index 6c889be..8676f6c 100644 --- a/src/ir/integer-type.h +++ b/src/ir/integer-type.h @@ -28,7 +28,7 @@ class IntegerTypeWrapper: public TypeWrapper, public FromValueMixin Date: Thu, 3 Jan 2019 20:56:42 -0800 Subject: [PATCH 20/23] Add floating point isNaN operation effectively Signed-off-by: Vihan --- src/ir/ir-builder.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index ee45bd3..f0fc8b4 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -92,6 +92,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createFCmpULT", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFCmpULT>>); Nan::SetPrototypeMethod(functionTemplate, "createFCmpUEQ", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFCmpUEQ>>); Nan::SetPrototypeMethod(functionTemplate, "createFCmpUNE", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFCmpUNE>>); + Nan::SetPrototypeMethod(functionTemplate, "createFCmpUNO", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFCmpUNO>>); Nan::SetPrototypeMethod(functionTemplate, "createFDiv", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFDiv>>); Nan::SetPrototypeMethod(functionTemplate, "createFMul", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateFMul>>); Nan::SetPrototypeMethod(functionTemplate, "createFNeg", IRBuilderWrapper::CreateFNeg); From 700295ac703ddcbb69f474f6ce00458494093572 Mon Sep 17 00:00:00 2001 From: Vihan Date: Wed, 16 Jan 2019 18:06:03 -0800 Subject: [PATCH 21/23] Add 'createUnreachable' Signed-off-by: Vihan --- llvm-node.d.ts | 2 ++ src/ir/ir-builder.cc | 7 +++++++ src/ir/ir-builder.h | 1 + 3 files changed, 10 insertions(+) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 7509b7c..edfcc8e 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -691,6 +691,8 @@ declare namespace llvm { createURem(lhs: Value, rhs: Value, name?: string): Value; + createUnreachable(): Value; + createZExt(value: Value, destType: Type, name?: string): Value; createZExtOrTrunc(value: Value, destType: Type, name?: string): Value; diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index f0fc8b4..e07e9f0 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -136,6 +136,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createSIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateSIToFP>); Nan::SetPrototypeMethod(functionTemplate, "createUDiv", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateUDiv>>); Nan::SetPrototypeMethod(functionTemplate, "createURem", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateURem>>); + Nan::SetPrototypeMethod(functionTemplate, "createUnreachable", IRBuilderWrapper::CreateUnreachable); Nan::SetPrototypeMethod(functionTemplate, "createUIToFP", &IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateUIToFP>); Nan::SetPrototypeMethod(functionTemplate, "createStore", IRBuilderWrapper::CreateStore); Nan::SetPrototypeMethod(functionTemplate, "createZExt", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateZExt>); @@ -641,6 +642,12 @@ NAN_METHOD(IRBuilderWrapper::CreateRetVoid) { info.GetReturnValue().Set(ValueWrapper::of(returnInstruction)); } +NAN_METHOD(IRBuilderWrapper::CreateUnreachable) { + auto& builder = IRBuilderWrapper::FromValue(info.Holder())->irBuilder; + auto* returnInstruction = builder.CreateUnreachable(); + info.GetReturnValue().Set(ValueWrapper::of(returnInstruction)); +} + NAN_METHOD(IRBuilderWrapper::CreateSelect) { if (info.Length() < 3 || !ValueWrapper::isInstance(info[0]) || !ValueWrapper::isInstance(info[1]) || !ValueWrapper::isInstance(info[2]) || (info.Length() == 4 && !(info[3]->IsString() || info[3]->IsUndefined())) || diff --git a/src/ir/ir-builder.h b/src/ir/ir-builder.h index c82d734..0c3a902 100644 --- a/src/ir/ir-builder.h +++ b/src/ir/ir-builder.h @@ -53,6 +53,7 @@ class IRBuilderWrapper: public Nan::ObjectWrap, public FromValueMixin Date: Sat, 8 Jun 2019 13:12:15 -0700 Subject: [PATCH 22/23] Add atomicRMW Signed-off-by: Vihan --- llvm-node.d.ts | 29 +++++++++++++++++++++++++++++ src/ir/atomic-rmw-inst.cc | 24 ++++++++++++++++++++++++ src/ir/atomic-rmw-inst.h | 8 ++++++++ src/ir/ir-builder.cc | 21 +++++++++++++++++++++ src/ir/ir.cc | 2 ++ src/support/atomic-ordering.cc | 15 +++++++++++++++ src/support/atomic-ordering.h | 8 ++++++++ src/support/support.cc | 14 ++++++++------ test/ir/ir-builder.spec.ts | 23 +++++++++++++++++++++++ 9 files changed, 138 insertions(+), 6 deletions(-) create mode 100644 src/ir/atomic-rmw-inst.cc create mode 100644 src/ir/atomic-rmw-inst.h create mode 100644 src/support/atomic-ordering.cc create mode 100644 src/support/atomic-ordering.h diff --git a/llvm-node.d.ts b/llvm-node.d.ts index 12d7ac2..a5195d7 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -98,6 +98,16 @@ declare namespace llvm { Protected } + enum AtomicOrdering { + NotAtomic, + Unordered, + Monotonic, + Acquire, + Release, + AcquireRelease, + SequentiallyConsistent + } + class Value { static MaxAlignmentExponent: number; static MaximumAlignment: number; @@ -568,6 +578,8 @@ declare namespace llvm { createAShr(lhs: Value, rhs: Value, name?: string): Value; + createAtomicRMW(op: AtomicRMWInst.BinOp, ptr: Value, value: Value, ordering: AtomicOrdering): Value; + createBitCast(value: Value, destType: Type, name?: string): Value; createBr(basicBlock: BasicBlock): Value; @@ -705,6 +717,23 @@ declare namespace llvm { getInsertBlock(): BasicBlock | undefined; } + namespace AtomicRMWInst { + enum BinOp { + Add, + Sub, + And, + Nand, + Or, + Xor, + Max, + Min, + UMax, + UMin, + FAdd, + FSub + } + } + class LLVMContext { constructor(); diff --git a/src/ir/atomic-rmw-inst.cc b/src/ir/atomic-rmw-inst.cc new file mode 100644 index 0000000..0977095 --- /dev/null +++ b/src/ir/atomic-rmw-inst.cc @@ -0,0 +1,24 @@ +#include +#include "atomic-rmw-inst.h" + +NAN_MODULE_INIT(InitAtomicRMWInst) { + auto atomicRMWInst = Nan::New(); + + auto binOp = Nan::New(); + Nan::Set(binOp, Nan::New("Add").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Add))); + Nan::Set(binOp, Nan::New("Sub").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Sub))); + Nan::Set(binOp, Nan::New("And").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::And))); + Nan::Set(binOp, Nan::New("Nand").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Nand))); + Nan::Set(binOp, Nan::New("Or").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Or))); + Nan::Set(binOp, Nan::New("Xor").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Xor))); + Nan::Set(binOp, Nan::New("Max").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Max))); + Nan::Set(binOp, Nan::New("Min").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Min))); + Nan::Set(binOp, Nan::New("UMax").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::UMax))); + Nan::Set(binOp, Nan::New("UMin").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::UMin))); + Nan::Set(binOp, Nan::New("FAdd").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::FAdd))); + Nan::Set(binOp, Nan::New("FSub").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::FSub))); + + Nan::Set(atomicRMWInst, Nan::New("BinOp").ToLocalChecked(), binOp); + + Nan::Set(target, Nan::New("AtomicRMWInst").ToLocalChecked(), atomicRMWInst); +} diff --git a/src/ir/atomic-rmw-inst.h b/src/ir/atomic-rmw-inst.h new file mode 100644 index 0000000..707db4d --- /dev/null +++ b/src/ir/atomic-rmw-inst.h @@ -0,0 +1,8 @@ +#ifndef LLVM_ATOMIC_RMW_INST_H +#define LLVM_ATOMIC_RMW_INST_H + +#include + +NAN_MODULE_INIT(InitAtomicRMWInst); + +#endif //LLVM_ATOMIC_RMW_INST_H diff --git a/src/ir/ir-builder.cc b/src/ir/ir-builder.cc index e07e9f0..658361a 100644 --- a/src/ir/ir-builder.cc +++ b/src/ir/ir-builder.cc @@ -74,6 +74,7 @@ NAN_MODULE_INIT(IRBuilderWrapper::Init) { Nan::SetPrototypeMethod(functionTemplate, "createAlignedStore", IRBuilderWrapper::CreateAlignedStore); Nan::SetPrototypeMethod(functionTemplate, "createAnd", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateAnd>>); Nan::SetPrototypeMethod(functionTemplate, "createAShr", &NANBinaryOperation<&ToBinaryOp<&llvm::IRBuilder<>::CreateAShr>>); + Nan::SetPrototypeMethod(functionTemplate, "createAtomicRMW", IRBuilderWrapper::CreateAtomicRMW); Nan::SetPrototypeMethod(functionTemplate, "createBitCast", IRBuilderWrapper::ConvertOperation<&llvm::IRBuilder<>::CreateBitCast>); Nan::SetPrototypeMethod(functionTemplate, "createBr", IRBuilderWrapper::CreateBr); Nan::SetPrototypeMethod(functionTemplate, "createCall", IRBuilderWrapper::CreateCall); @@ -267,6 +268,26 @@ NAN_METHOD(IRBuilderWrapper::CreateAlloca) { info.GetReturnValue().Set(AllocaInstWrapper::of(alloc)); } +NAN_METHOD(IRBuilderWrapper::CreateAtomicRMW) { + if (info.Length() < 4 || !info[0]->IsUint32() + || !ValueWrapper::isInstance(info[1]) + || !ValueWrapper::isInstance(info[2]) + || !info[3]->IsUint32()) { + return Nan::ThrowTypeError("createAtomicRMW needs to be called with: op: AtomicRMWInst.BinOp, ptr: Value, value: Value, ordering: AtomicOrdering"); + } + + auto& irBuilder = IRBuilderWrapper::FromValue(info.This())->getIRBuilder(); + + auto op = static_cast(Nan::To(info[0]).FromJust()); + llvm::Value *ptr = ValueWrapper::FromValue(info[1])->getValue(); + llvm::Value *value = ValueWrapper::FromValue(info[2])->getValue(); + auto ordering = static_cast(Nan::To(info[3]).FromJust()); + + auto *instruction = irBuilder.CreateAtomicRMW(op, ptr, value, ordering); + + info.GetReturnValue().Set(ValueWrapper::of(instruction)); +} + NAN_METHOD(IRBuilderWrapper::CreateExtractValue) { if (info.Length() < 2 || !ValueWrapper::isInstance(info[0]) || !info[1]->IsArray() || (info.Length() > 2 && !(info[2]->IsString() || info[2]->IsUndefined())) || diff --git a/src/ir/ir.cc b/src/ir/ir.cc index 840d970..e88ff18 100644 --- a/src/ir/ir.cc +++ b/src/ir/ir.cc @@ -33,12 +33,14 @@ #include "visibility-types.h" #include "constant-aggregate-zero.h" #include "attribute.h" +#include "atomic-rmw-inst.h" #include "undef-value.h" #include "constant-expr.h" #include "integer-type.h" NAN_MODULE_INIT(InitIR) { AllocaInstWrapper::Init(target); + InitAtomicRMWInst(target); ArgumentWrapper::Init(target); ArrayTypeWrapper::Init(target); InitAttribute(target); diff --git a/src/support/atomic-ordering.cc b/src/support/atomic-ordering.cc new file mode 100644 index 0000000..2302a33 --- /dev/null +++ b/src/support/atomic-ordering.cc @@ -0,0 +1,15 @@ +#include +#include "atomic-ordering.h" + +NAN_MODULE_INIT(InitAtomicOrdering) { + auto atomicOrdering = Nan::New(); + Nan::Set(atomicOrdering, Nan::New("NotAtomic").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::NotAtomic))); + Nan::Set(atomicOrdering, Nan::New("Unordered").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::Unordered))); + Nan::Set(atomicOrdering, Nan::New("Monotonic").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::Monotonic))); + Nan::Set(atomicOrdering, Nan::New("Acquire").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::Acquire))); + Nan::Set(atomicOrdering, Nan::New("Release").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::Release))); + Nan::Set(atomicOrdering, Nan::New("AcquireRelease").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::AcquireRelease))); + Nan::Set(atomicOrdering, Nan::New("SequentiallyConsistent").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicOrdering::SequentiallyConsistent))); + + Nan::Set(target, Nan::New("AtomicOrdering").ToLocalChecked(), atomicOrdering); +} diff --git a/src/support/atomic-ordering.h b/src/support/atomic-ordering.h new file mode 100644 index 0000000..6c17684 --- /dev/null +++ b/src/support/atomic-ordering.h @@ -0,0 +1,8 @@ +#ifndef LLVM_NODE_ATOMIC_ORDERING_H +#define LLVM_NODE_ATOMIC_ORDERING_H + +#include + +NAN_MODULE_INIT(InitAtomicOrdering); + +#endif //LLVM_NODE_ATOMIC_ORDERING_H diff --git a/src/support/support.cc b/src/support/support.cc index e74c31b..9785562 100644 --- a/src/support/support.cc +++ b/src/support/support.cc @@ -1,5 +1,6 @@ #include #include "support.h" +#include "atomic-ordering.h" NAN_METHOD(InitializeAllTargetInfos) { llvm::InitializeAllTargetInfos(); @@ -22,31 +23,32 @@ NAN_METHOD(InitializeAllAsmPrinters) { } NAN_MODULE_INIT(InitSupport) { - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllTargetInfos").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllTargetInfos)).ToLocalChecked() ); - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllTargets").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllTargets)).ToLocalChecked() ); - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllTargetMCs").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllTargetMCs)).ToLocalChecked() ); - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllAsmParsers").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllAsmParsers)).ToLocalChecked() ); - Nan::Set(target, + Nan::Set(target, Nan::New("initializeAllAsmPrinters").ToLocalChecked(), Nan::GetFunction(Nan::New(InitializeAllAsmPrinters)).ToLocalChecked() ); + InitAtomicOrdering(target); TargetRegistryWrapper::Init(target); TargetWrapper::Init(target); -} \ No newline at end of file +} diff --git a/test/ir/ir-builder.spec.ts b/test/ir/ir-builder.spec.ts index b11b56e..8ace5ce 100644 --- a/test/ir/ir-builder.spec.ts +++ b/test/ir/ir-builder.spec.ts @@ -78,6 +78,29 @@ describe("IRBuilder", () => { expect(ashr).toEqual(llvm.ConstantInt.get(context, 2)); }); + test("create createAtomicRMW returns a value", () => { + const { builder, context } = createBuilderWithBlock(); + + // let %0: i32 = 3; + const value = builder.createAlloca( + llvm.Type.getInt32Ty(context) + ); + + builder.createStore( + llvm.ConstantInt.get(context, 3), + value + ); + + const atomicRMW = builder.createAtomicRMW( + llvm.AtomicRMWInst.BinOp.Add, + value, + llvm.ConstantInt.get(context, 1), + llvm.AtomicOrdering.AcquireRelease + ); + + expect(atomicRMW).toBeInstanceOf(llvm.Value); + }); + test("createBitCast returns a value", () => { const { builder, context } = createBuilderWithBlock(); From 827a1b3ed90ab2b5f0a785d60519497504278c3b Mon Sep 17 00:00:00 2001 From: Vihan Date: Mon, 29 Jul 2019 18:38:16 -0700 Subject: [PATCH 23/23] Remove invalid fops for rmw operations. Signed-off-by: Vihan --- llvm-node.d.ts | 4 +--- src/ir/atomic-rmw-inst.cc | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/llvm-node.d.ts b/llvm-node.d.ts index a5195d7..6ba9ca2 100644 --- a/llvm-node.d.ts +++ b/llvm-node.d.ts @@ -728,9 +728,7 @@ declare namespace llvm { Max, Min, UMax, - UMin, - FAdd, - FSub + UMin } } diff --git a/src/ir/atomic-rmw-inst.cc b/src/ir/atomic-rmw-inst.cc index 0977095..48991c6 100644 --- a/src/ir/atomic-rmw-inst.cc +++ b/src/ir/atomic-rmw-inst.cc @@ -15,8 +15,6 @@ NAN_MODULE_INIT(InitAtomicRMWInst) { Nan::Set(binOp, Nan::New("Min").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::Min))); Nan::Set(binOp, Nan::New("UMax").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::UMax))); Nan::Set(binOp, Nan::New("UMin").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::UMin))); - Nan::Set(binOp, Nan::New("FAdd").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::FAdd))); - Nan::Set(binOp, Nan::New("FSub").ToLocalChecked(), Nan::New(static_cast(llvm::AtomicRMWInst::BinOp::FSub))); Nan::Set(atomicRMWInst, Nan::New("BinOp").ToLocalChecked(), binOp);