Skip to content

Commit

Permalink
Added a test case with more than 6 args, which made me realize I need…
Browse files Browse the repository at this point in the history
…ed to implement support for calling more than 6 args, which I did. Also fixed a stupid bug in my argument register->var mapping algorithm, which I fixed. Also fixed a bug where the type checker only checked up to the passed in arg, meaning f(int,int) would pass when the actual f is intXintXint, and so on
  • Loading branch information
chutasano committed Apr 8, 2018
1 parent b4885dd commit 60efb49
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 18 deletions.
2 changes: 1 addition & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ int main(int argc, char* argv[])
bool last_test_only = false;
for (int i=argc; i>1; i--)
{
if (!strcmp("--last_test_only", argv[i-1]))
if (!strcmp("--last_test_only", argv[i-1]) || !strcmp("-l", argv[i-1]))
{
last_test_only = true;
}
Expand Down
2 changes: 1 addition & 1 deletion rep/c0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ list<x0s::I*> Unop::select(x0s::Var* var)

list<x0s::I*> FunCall::select(x0s::Var* var)
{
list<x0s::Arg*> x0sargs;
vector<x0s::Arg*> x0sargs;
for (auto a : args)
{
x0sargs.push_back(a->to_arg());
Expand Down
4 changes: 2 additions & 2 deletions rep/c0.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ namespace c0

struct FunCall : E
{
FunCall(std::string name, std::list<Arg*> args) : name(name), args(args) { }
FunCall(std::string name, std::vector<Arg*> args) : name(name), args(args) { }
~FunCall() { for (auto a : args) delete a; }
std::string name;
std::list<Arg*> args;
std::vector<Arg*> args;
std::list<x0s::I*> select(x0s::Var*);
};

Expand Down
3 changes: 2 additions & 1 deletion rep/r0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ c0::Arg* Call::to_c0(unordered_map<string, int> &vars, vector<c0::AS*> &stmts) c
{
string s = gensym("r0Call");
vars[s] = t;
list<c0::Arg*> c0args;
vector<c0::Arg*> c0args;
for (E* e : args)
{
c0args.push_back(e->to_c0(vars, stmts));
Expand All @@ -601,6 +601,7 @@ int Call::t_check(unordered_map<string, int> vmap)
{
int i = 0;
auto t_vec = fun_type.at(vmap.at(name));
assert(args.size() == t_vec.size()-1);
for (E* e : args)
{
int t_arg = e->t_check(vmap);
Expand Down
26 changes: 16 additions & 10 deletions rep/x0s.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <algorithm>
#include <array>
#include <algorithm>
#include <iterator>
#include <list>
#include <string>
Expand Down Expand Up @@ -59,7 +59,11 @@ list<x0::I*> F::assign(bool is_default, int heap_size)
}
// get lifetime of all vars
unordered_map<string, pair<int, int> > lifetime;

// all function arguments should be alive since day one
for (auto s : args)
{
lifetime[s] = make_pair(1, 1);
}
int i = 1; // let i start at 1 to exploit the default constructor
// of std::pair to check for initial existance
vector<pair<ICollect*, int> > collects;
Expand Down Expand Up @@ -234,7 +238,7 @@ list<x0::I*> F::assign(bool is_default, int heap_size)
{
for (; it != reg2arg.end(); ++it) // search for conflicts
{
if ((int)vmap.at(it->second.var).first == next->first)
if ((int)vmap.at(next->second.var).first == it->first)
{
break;
}
Expand Down Expand Up @@ -528,24 +532,26 @@ list <x0::I*> ICollect::assign(const s2vmap &vmap)

list<x0::I*> ICall::assign(const s2vmap &vmap)
{

if (args.size() > 6)
{
cerr << "ERROR: more than 6 args for function not supported atm.\n";
exit(1);
}
list<x0::I*> a;
for (unsigned int i=0; i<callers.size(); i++)
{
a.push_back(new x0::ISrc(PUSHQ, new x0::Reg(callers.at(i))));
}
for(auto it_pair = make_pair(args.begin(), callers.begin());
it_pair.first != args.end();
it_pair.first != args.end() && it_pair.second != callers.end();
++it_pair.first, ++it_pair.second)
{
a.push_back(new x0::ISrcDst(MOVQ, (*it_pair.first)->assign(vmap), new x0::Reg(*it_pair.second)));
}
for (unsigned int i=callers.size(); i<args.size(); i++)
{
a.push_back(new x0::ISrc(PUSHQ, args.at(args.size()-i-1)->assign(vmap)));
}
a.push_back(new x0::ICall(this->label));
if (args.size() > callers.size())
{
a.push_back(new x0::ISrcDst(ADDQ, new x0::Con(8*(args.size()-callers.size())), new x0::Reg("rsp")));
}
for (unsigned int i=0; i<callers.size(); i++)
{
a.push_back(new x0::IDst(POPQ, new x0::Reg(callers.at(callers.size()-i-1))));
Expand Down
4 changes: 2 additions & 2 deletions rep/x0s.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,10 @@ namespace x0s
// abstraction of function calls
struct ICall : I
{
ICall(std::string l, std::list<Arg*> args, Dst* dst) : label(l), args(args), dst(dst) { }
ICall(std::string l, std::vector<Arg*> args, Dst* dst) : label(l), args(args), dst(dst) { }
~ICall() { for (auto a : args) {delete a;} delete dst; }
std::string label;
std::list<Arg*> args;
std::vector<Arg*> args;
Dst* dst;
std::list<x0::I*> assign(const s2vmap&);
std::list<std::string> get_vars();
Expand Down
30 changes: 29 additions & 1 deletion test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type * name = & name ## _LOCAL
// operation specifics, might be too much work to maintain if we add more operators

#define PLUS(lexp, rexp) BINOP(bplus_ ## lexp ## _ ## rexp, B_PLUS, lexp, rexp)
#define PLUSN(name, lexp, rexp) BINOP(name, B_PLUS, lexp, rexp)
#define EQ(lexp, rexp) BINOP(beq_ ## lexp ## _ ## rexp, B_EQ, lexp, rexp)
#define LT(lexp, rexp) BINOP(blt_ ## lexp ## _ ## rexp, B_LT, lexp, rexp)
#define GT(lexp, rexp) BINOP(bgt_ ## lexp ## _ ## rexp, B_GT, lexp, rexp)
Expand Down Expand Up @@ -472,7 +473,7 @@ void test_all(bool run_only_last = false)

}

ts("Simple functions");
ts("Simple Fibonacci w/ Recursion");
{
NUM(0);
NUM(1);
Expand All @@ -495,6 +496,33 @@ void test_all(bool run_only_last = false)
r0::P prog = r0::P({fib, main }, "main", 2048);
t(prog, 55);
}

ts("Function with lots of args");
{
r0::Var n0 = r0::Var("n0", TNUM); r0::Var n1 = r0::Var("n1", TNUM);
r0::Var n2 = r0::Var("n2", TNUM); r0::Var n3 = r0::Var("n3", TNUM);
r0::Var n4 = r0::Var("n4", TNUM); r0::Var n5 = r0::Var("n5", TNUM);
r0::Var n6 = r0::Var("n6", TNUM); r0::Var n7 = r0::Var("n7", TNUM);
r0::Var n8 = r0::Var("n8", TNUM); r0::Var n9 = r0::Var("n9", TNUM);
r0::Var n10 = r0::Var("n10", TNUM); r0::Var n11 = r0::Var("n11", TNUM);
r0::Var n12 = r0::Var("n12", TNUM);
auto rn0 = &n0; auto rn1 = &n1; auto rn2 = &n2; auto rn3 = &n3;
auto rn4 = &n4; auto rn5 = &n5; auto rn6 = &n6; auto rn7 = &n7;
auto rn8 = &n8; auto rn9 = &n9; auto rn10 = &n10; auto rn11 = &n11;
auto rn12 = &n12;
PLUSN(p01, rn0, rn1); PLUSN(p02, p01, rn2); PLUSN(p03, p02, rn3);
PLUSN(p04, p03, rn4); PLUSN(p05, p04, rn5); PLUSN(p06, p05, rn6);
PLUSN(p07, p06, rn7); PLUSN(p08, p07, rn8); PLUSN(p09, p08, rn9);
PLUSN(p010, p09, rn10); PLUSN(p011, p010, rn11); PLUSN(p012, p011, rn12);
r0::F add_12_nums = r0::F("add_12_nums",
{n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12},
TNUM, p012);
NUM(20);
UPTR(r0::Call, call_12_nums, "add_12_nums", {n20,n20,n20,n20,n20,n20,n20,n20,n20,n20,n20,n20, n20});
r0::F main = r0::F("main", { }, call_12_nums);
r0::P prog = r0::P({add_12_nums, main }, "main", 2048);
t(prog, 20*13);
}
cout << "Total tests failed: " << fails << endl;
}

0 comments on commit 60efb49

Please sign in to comment.