From 218bacc725a7153a80112de2ea1e48f10712a568 Mon Sep 17 00:00:00 2001 From: oli Date: Fri, 9 Apr 2021 09:39:23 +0000 Subject: [PATCH] refactoring a bit --- rir/src/compiler/gnur2pir/gnur2pir.cpp | 124 ++++++++++++++++++------- rir/src/compiler/opt/inline.cpp | 5 +- rir/tests/gnur2pir.R | 10 ++ 3 files changed, 106 insertions(+), 33 deletions(-) create mode 100644 rir/tests/gnur2pir.R diff --git a/rir/src/compiler/gnur2pir/gnur2pir.cpp b/rir/src/compiler/gnur2pir/gnur2pir.cpp index 1a5029543..4a791dc4d 100644 --- a/rir/src/compiler/gnur2pir/gnur2pir.cpp +++ b/rir/src/compiler/gnur2pir/gnur2pir.cpp @@ -368,9 +368,26 @@ class RBCCode { } }; +struct Stack { + private: + std::stack 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 mergepoints; std::unordered_map jumps; }; @@ -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 + void compile(RBC); +}; + +// Start instructions translation + +template <> +void BCCompiler::compile(RBC bc) { + auto v = insert(new LdVar(cnst(bc.imm(0)), env())); + insertPush(new Force(v, env(), Tombstone::framestate())); +} + +template <> +void BCCompiler::compile(RBC bc) { + insert(new Return(pop())); +} + +template <> +void BCCompiler::compile(RBC bc) { + push(insert(new LdConst(cnst(bc.imm(0))))); +} + +template <> +void BCCompiler::compile(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 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); \ + break; + SUPPORTED_INSTRUCTIONS(V) +#undef V + default: std::cerr << "Could not compile " << *pc << "\n"; + assert(false); return nullptr; } } diff --git a/rir/src/compiler/opt/inline.cpp b/rir/src/compiler/opt/inline.cpp index 1df803065..88ac8b86e 100644 --- a/rir/src/compiler/opt/inline.cpp +++ b/rir/src/compiler/opt/inline.cpp @@ -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; }; diff --git a/rir/tests/gnur2pir.R b/rir/tests/gnur2pir.R new file mode 100644 index 000000000..ea70d96d8 --- /dev/null +++ b/rir/tests/gnur2pir.R @@ -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)