Skip to content

Commit

Permalink
refactoring a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
o- committed Apr 9, 2021
1 parent bd2bb2b commit 218bacc
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 33 deletions.
124 changes: 93 additions & 31 deletions rir/src/compiler/gnur2pir/gnur2pir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,26 @@ class RBCCode {
}
};

struct Stack {
private:
std::stack<Value*> stack;

public:
void push(Value* v) { stack.push(v); }
Value* pop() {
auto v = stack.top();
stack.pop();
return v;
}
~Stack() { assert(stack.empty()); }
};

struct CompilerInfo {
CompilerInfo(SEXP src) : src(src) {}
CompilerInfo(SEXP src, Stack& stack, Builder& insert)
: src(src), stack(stack), insert(insert) {}
SEXP src;
Stack& stack;
Builder& insert;
std::unordered_set<size_t> mergepoints;
std::unordered_map<size_t, size_t> jumps;
};
Expand Down Expand Up @@ -407,57 +424,102 @@ static void findMerges(const RBCCode& bytecode, CompilerInfo& info) {
info.mergepoints.insert(m.first);
}

struct BCCompiler {
CompilerInfo& cmp;
BCCompiler(CompilerInfo& cmp) : cmp(cmp) {}

void push(Value* v) { cmp.stack.push(v); }

Value* pop() { return cmp.stack.pop(); }

Instruction* insertPush(Instruction* i) {
push(insert(i));
return i;
}

Instruction* insert(Instruction* i) {
cmp.insert(i);
return i;
}

SEXP cnst(int i) { return VECTOR_ELT(BCODE_CONSTS(BODY(cmp.src)), i); }

Value* env() { return cmp.insert.env; }

template <RBC::Id BC>
void compile(RBC);
};

// Start instructions translation

template <>
void BCCompiler::compile<RBC::GETVAR_OP>(RBC bc) {
auto v = insert(new LdVar(cnst(bc.imm(0)), env()));
insertPush(new Force(v, env(), Tombstone::framestate()));
}

template <>
void BCCompiler::compile<RBC::RETURN_OP>(RBC bc) {
insert(new Return(pop()));
}

template <>
void BCCompiler::compile<RBC::LDCONST_OP>(RBC bc) {
push(insert(new LdConst(cnst(bc.imm(0)))));
}

template <>
void BCCompiler::compile<RBC::ADD_OP>(RBC bc) {
auto a = pop();
auto b = pop();
insertPush(new Add(a, b, env(), bc.imm(0)));
}

// End instructions translation

pir::ClosureVersion* Gnur2Pir::compile(SEXP src, const std::string& name) {
SEXP body = BODY(src);
RBCCode bytecode(body);
SEXP consts = BCODE_CONSTS(body);
auto cnst = [&](int i) { return VECTOR_ELT(consts, i); };

std::cout << bytecode;

CompilerInfo info(src);
auto c = m.getOrDeclareGnurClosure(name, src, Context());
auto v = c->declareVersion(Compiler::defaultContext, true, nullptr);

Stack stack;
Builder insert(v, c->closureEnv());

CompilerInfo info(src, stack, insert);

findMerges(bytecode, info);

std::cout << "Merges at: ";
std::cout << "CFG merges at: ";
for (auto& m : info.mergepoints) {
std::cout << m << " ";
}
std::cout << "\n";

auto c = m.getOrDeclareGnurClosure(name, src, Context());
auto v = c->declareVersion(Compiler::defaultContext, true, nullptr);

Builder insert(v, c->closureEnv());
BCCompiler bccompiler(info);

struct Stack {
private:
std::stack<Value*> stack;
#define SUPPORTED_INSTRUCTIONS(V) \
V(RBC::GETVAR_OP) \
V(RBC::RETURN_OP) \
V(RBC::LDCONST_OP) \
V(RBC::ADD_OP)

public:
void push(Value* v) { stack.push(v); }
Value* pop() {
auto v = stack.top();
stack.pop();
return v;
}
~Stack() { assert(stack.empty()); }
};
Stack stack;
for (auto pc = bytecode.begin(); pc != bytecode.end(); ++pc) {
auto bc = *pc;
switch (bc.id) {
case RBC::GETVAR_OP: {
auto v = insert(new LdVar(cnst(bc.imm(0)), insert.env));
stack.push(
insert(new Force(v, insert.env, Tombstone::framestate())));
break;
}
case RBC::RETURN_OP:
insert(new Return(stack.pop()));
break;
#define V(BC) \
case BC: \
bccompiler.compile<BC>(bc); \
break;
SUPPORTED_INSTRUCTIONS(V)
#undef V

default:
std::cerr << "Could not compile " << *pc << "\n";
assert(false);
return nullptr;
}
}
Expand Down
5 changes: 3 additions & 2 deletions rir/src/compiler/opt/inline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ bool Inline::apply(Compiler&, ClosureVersion* cls, Code* code,
cls->rirFunction([&](rir::Function* f) {
if (f->flags.contains(rir::Function::DisableInline))
res = true;
if (f->flags.contains(rir::Function::ForceInline))
else if (f->flags.contains(rir::Function::ForceInline))
res = false;
res = f->flags.contains(rir::Function::NotInlineable);
else
res = f->flags.contains(rir::Function::NotInlineable);
});
return res;
};
Expand Down
10 changes: 10 additions & 0 deletions rir/tests/gnur2pir.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
test <- function(f, arg, expected) {
f = compiler::cmpfun(f)
compiler::disassemble(f)
.Call('gnur2pir', f)
stopifnot(identical(f(arg), expected))
}

test(function(a) 1,, 1)
test(function(a) a, 1, 1)
test(function(a) a+1, 1, 2)

0 comments on commit 218bacc

Please sign in to comment.