Skip to content

exam #1

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 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.swp
build/
3 changes: 3 additions & 0 deletions compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,9 @@ class Compiler : public Visitor {
case ast::BinExp::Type::gt:
result = RUNTIME_CALL(genericGt, lhs, rhs);
return;
case ast::BinExp::Type::dot:
result = RUNTIME_CALL(genericDot, lhs, rhs);
return;
default: // can't happen
return;
}
Expand Down
13 changes: 11 additions & 2 deletions runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,11 +526,20 @@ RVal * c(int size, ...) {
}

double doubleDot(DoubleVector * lhs, DoubleVector * rhs) {
assert(false and "Fill me in");
int mLen = std::max(lhs->size, rhs->size);
double res = 0;

for(int i = 0; i < mLen; i++)
{
res += lhs->data[i % lhs->size] * rhs->data[i % rhs->size];
}
return res;
}

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 to dot product must be double vectors";
return new RVal(new DoubleVector(doubleDot(lhs->d, rhs->d)));
}


Expand Down
13 changes: 7 additions & 6 deletions tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ namespace rift {
TEST("(f = function(a, b) { a %*% b })(c(1,2,3), c(3,2,1))", 10);
TEST("(f = function(a, b) { a %*% b })(c(1,2,3), 3)", 18);
TEST("(f = function(a, b) { a %*% b })(10, 2)", 20);
TEST("(f = function(a, b) { a %*% b })(c(1,2,3,4), c(5,6))", 5 + 6 * 2 + 3 * 5 + 4 * 6);
TEST("(f = function(a, b) { a %*% b })(c(1,2,3,4), c(5,6))", 1*5 + 2*6 + 3*5 + 4*6);
TEST("(f = function(a, b) { a %*% b })(c(1,2), c(5))", 1*5 + 2*5);
}

/** Checks that a dot operator result type is correctly set to be double scalar by the type analysis. */
Expand Down Expand Up @@ -222,11 +223,11 @@ 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();
project3();
project4();
project5();
project6();
}

} // namespace rift
3 changes: 3 additions & 0 deletions type_analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ bool TypeAnalysis::runOnFunction(llvm::Function & f) {
genericRelational(ci);
} else if (s == "genericGt") {
genericRelational(ci);
} else if (s == "genericDot") {
// DV with len 1 is R->DV->D?
state.update(ci, new AType(AType::Kind::R, new AType(AType::Kind::DV, new AType(AType::Kind::D))));
} else if (s == "length") {
// result of length operation is always
// double scalar
Expand Down
26 changes: 26 additions & 0 deletions unboxing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,30 @@ bool Unboxing::genericArithmetic(llvm::Instruction::BinaryOps op, llvm::Function
}
}

bool Unboxing::genericDot() {
AType *lhs = state().get(ins->getOperand(0));
AType *rhs = state().get(ins->getOperand(1));
AType *result_t;

// both must be doubles
if(not lhs->isDouble() or not rhs->isDouble()) {
return false;
}

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;
}

void Unboxing::doubleRelational(AType * lhs, AType * rhs, llvm::CmpInst::Predicate op, llvm::Function * fop) {
assert(lhs->isDouble() and rhs->isDouble() and "Doubles expected");
AType * result_t;
Expand Down Expand Up @@ -337,6 +361,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") {
Expand Down
2 changes: 2 additions & 0 deletions unboxing.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class Unboxing : public llvm::FunctionPass {

void doubleArithmetic(AType * lhs, AType * rhs, llvm::Instruction::BinaryOps op, llvm::Function * fop);

bool genericDot();

bool genericAdd();

bool genericArithmetic(llvm::Instruction::BinaryOps op, llvm::Function * fop);
Expand Down