From 86f4df5b0ad47eceb46e381a38ae2db2f6d915c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 19:54:36 +0100 Subject: [PATCH 01/10] Enabled second test. --- tests.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests.cpp b/tests.cpp index fe05cac..769fa1a 100644 --- a/tests.cpp +++ b/tests.cpp @@ -222,11 +222,7 @@ namespace rift { TEST("a = \"aba\" a[c(0,2)]", "aa"); TEST("a = c(1,2,3) a[c(0,1)] = 56 a", 56, 56, 3); - // project2(); - // project3(); - // project4(); - // project5(); - // project6(); + project2(); } } // namespace rift From 6eff56d9a8066e13acf79bc02cbb21bed3cfa9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 19:56:55 +0100 Subject: [PATCH 02/10] Compiler now emits runtime call to genericDot for AST dot node. --- compiler.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler.cpp b/compiler.cpp index 606a455..23d027d 100644 --- a/compiler.cpp +++ b/compiler.cpp @@ -378,6 +378,9 @@ class Compiler : public Visitor { case ast::BinExp::Type::div: result = RUNTIME_CALL(genericDiv, lhs, rhs); return; + case ast::BinExp::Type::dot: + result = RUNTIME_CALL(genericDot, lhs, rhs); + return; case ast::BinExp::Type::eq: result = RUNTIME_CALL(genericEq, lhs, rhs); return; From dad057fa74f901636d6e748c13a13ac079a914cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 19:57:56 +0100 Subject: [PATCH 03/10] Enabled third test. --- tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests.cpp b/tests.cpp index 769fa1a..53cd210 100644 --- a/tests.cpp +++ b/tests.cpp @@ -223,6 +223,7 @@ namespace rift { TEST("a = c(1,2,3) a[c(0,1)] = 56 a", 56, 56, 3); project2(); + project3(); } } // namespace rift From 64a15366e16f82cc2d77dde5def974f3a1084c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 20:22:36 +0100 Subject: [PATCH 04/10] Implemented double dot on DoubleVectors. --- runtime.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runtime.cpp b/runtime.cpp index c1bdd1f..9c145e3 100644 --- a/runtime.cpp +++ b/runtime.cpp @@ -526,7 +526,11 @@ RVal * c(int size, ...) { } double doubleDot(DoubleVector * lhs, DoubleVector * rhs) { - assert(false and "Fill me in"); + int vectorSize = max(lhs->size, rhs->size); + double result = 0; + for (int i = 0; i < vectorSize; ++i) + result += lhs->data[i % lhs->size] * rhs->data[i % rhs->size]; + return result; } RVal * genericDot(RVal * lhs, RVal * rhs) { From 9e4f935863b646dc6d65c4ffe0fed5be3b7844dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 20:25:40 +0100 Subject: [PATCH 05/10] Implemented generic dot for boxed values. --- runtime.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime.cpp b/runtime.cpp index 9c145e3..dcff9e0 100644 --- a/runtime.cpp +++ b/runtime.cpp @@ -534,7 +534,9 @@ double doubleDot(DoubleVector * lhs, DoubleVector * rhs) { } RVal * genericDot(RVal * lhs, RVal * rhs) { - assert(false and "Fill me in"); + if (lhs->type != RVal::Type::Double || rhs->type != RVal::Type::Double) + throw "Both operands of dot product have to be double vectors"; + return new RVal(new DoubleVector(doubleDot(lhs->d, rhs->d))); } From 080464ae3ae6cc11277881bac1f05deaf91f07d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 20:27:41 +0100 Subject: [PATCH 06/10] Enabled fourth test. --- tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests.cpp b/tests.cpp index 53cd210..8cc419b 100644 --- a/tests.cpp +++ b/tests.cpp @@ -224,6 +224,7 @@ namespace rift { project2(); project3(); + project4(); } } // namespace rift From 57906f02f720913a951c0ff1595afb3ad5a6ab9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 20:37:24 +0100 Subject: [PATCH 07/10] Static analysis now produces correct abstract values for genericDot. --- type_analysis.cpp | 6 ++++++ type_analysis.h | 1 + 2 files changed, 7 insertions(+) diff --git a/type_analysis.cpp b/type_analysis.cpp index 136e3f7..f6f65df 100644 --- a/type_analysis.cpp +++ b/type_analysis.cpp @@ -22,6 +22,10 @@ void TypeAnalysis::genericArithmetic(CallInst * ci) { state.update(ci, lhs->merge(rhs)); } +void TypeAnalysis::genericDot(CallInst * ci) { + state.update(ci, new AType(AType::Kind::R, AType::Kind::DV, AType::Kind::D)); +} + void TypeAnalysis::genericRelational(CallInst * ci) { AType * lhs = state.get(ci->getOperand(0)); AType * rhs = state.get(ci->getOperand(1)); @@ -100,6 +104,8 @@ bool TypeAnalysis::runOnFunction(llvm::Function & f) { genericArithmetic(ci); } else if (s == "genericDiv") { genericArithmetic(ci); + } else if (s == "genericDot") { + genericDot(ci); } else if (s == "genericEq") { genericRelational(ci); } else if (s == "genericNeq") { diff --git a/type_analysis.h b/type_analysis.h index 79f3d7e..55cb23c 100644 --- a/type_analysis.h +++ b/type_analysis.h @@ -218,6 +218,7 @@ class TypeAnalysis : public llvm::FunctionPass { private: void genericArithmetic(llvm::CallInst * ci); + void genericDot(llvm::CallInst * ci); void genericRelational(llvm::CallInst * ci); void genericGetElement(llvm::CallInst * ci); From 0ae132b422519fe9f7b4c6d55fd1c6ad1422046a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 20:48:01 +0100 Subject: [PATCH 08/10] Enabled fifth and sixth test. --- tests.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests.cpp b/tests.cpp index 8cc419b..f347ccb 100644 --- a/tests.cpp +++ b/tests.cpp @@ -225,6 +225,8 @@ namespace rift { project2(); project3(); project4(); + project5(); + project6(); } } // namespace rift From bcd2b8f9843d3391d2bd015a15cb3a44dc21ec58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 20:48:43 +0100 Subject: [PATCH 09/10] Added unboxing for dot product. --- unboxing.cpp | 21 +++++++++++++++++++++ unboxing.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/unboxing.cpp b/unboxing.cpp index 2b11f32..76aed14 100644 --- a/unboxing.cpp +++ b/unboxing.cpp @@ -158,6 +158,25 @@ bool Unboxing::genericAdd() { } } +bool Unboxing::genericDot() { + AType * lhs = state().get(ins->getOperand(0)); + AType * rhs = state().get(ins->getOperand(1)); + if (!lhs->isDouble() || !rhs->isDouble()) + return false; + AType * result_t; + if (lhs->isScalar() and rhs->isScalar()) { + result_t = updateAnalysis( + BinaryOperator::Create(Instruction::FMul, getScalarPayload(lhs), getScalarPayload(rhs), "", ins), + new AType(AType::Kind::D)); + } else { + result_t = updateAnalysis( + RUNTIME_CALL(m->doubleDot, getVectorPayload(lhs), getVectorPayload(rhs)), + new AType(AType::Kind::D)); + } + ins->replaceAllUsesWith(box(result_t)); + return true; +} + bool Unboxing::genericArithmetic(llvm::Instruction::BinaryOps op, llvm::Function * fop) { AType * lhs = state().get(ins->getOperand(0)); AType * rhs = state().get(ins->getOperand(1)); @@ -337,6 +356,8 @@ bool Unboxing::runOnFunction(llvm::Function & f) { erase = genericArithmetic(Instruction::FMul, m->doubleMul); } else if (s == "genericDiv") { erase = genericArithmetic(Instruction::FDiv, m->doubleDiv); + } else if (s == "genericDot") { + erase = genericDot(); } else if (s == "genericLt") { erase = genericRelational(FCmpInst::FCMP_OLT, m->doubleLt); } else if (s == "genericGt") { diff --git a/unboxing.h b/unboxing.h index bb134c1..cf70169 100644 --- a/unboxing.h +++ b/unboxing.h @@ -48,6 +48,8 @@ class Unboxing : public llvm::FunctionPass { bool genericAdd(); + bool genericDot(); + bool genericArithmetic(llvm::Instruction::BinaryOps op, llvm::Function * fop); void doubleRelational(AType * lhs, AType * rhs, llvm::CmpInst::Predicate op, llvm::Function * fop); From d58fc93d10471128fa0527d08ab01c82b9b564ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ko=C4=8Di=C4=8Dka?= Date: Sat, 5 Dec 2015 20:55:53 +0100 Subject: [PATCH 10/10] Added optimization for dot product with vector of length one. --- runtime.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/runtime.cpp b/runtime.cpp index dcff9e0..5f0c3a5 100644 --- a/runtime.cpp +++ b/runtime.cpp @@ -526,10 +526,24 @@ RVal * c(int size, ...) { } double doubleDot(DoubleVector * lhs, DoubleVector * rhs) { - int vectorSize = max(lhs->size, rhs->size); double result = 0; - for (int i = 0; i < vectorSize; ++i) - result += lhs->data[i % lhs->size] * rhs->data[i % rhs->size]; + int vectorSize = max(lhs->size, rhs->size); + if (lhs->size == 1 || rhs->size == 1) { + double scalar; + double *doubleVector; + if (lhs->size == 1) { + scalar = lhs->data[0]; + doubleVector = rhs->data; + } else { + scalar = rhs->data[0]; + doubleVector = lhs->data; + } + for (int i = 0; i < vectorSize; ++i) + result += scalar * doubleVector[i % vectorSize]; + } else { + for (int i = 0; i < vectorSize; ++i) + result += lhs->data[i % lhs->size] * rhs->data[i % rhs->size]; + } return result; }