[hackers] [scc] [cc2-qbe] Ensure correctness of basic blocks || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Mon, 9 May 2016 17:00:22 +0200 (CEST)

commit 2f85abe8f705f3fe4b60a58f94b15c8bd0f314d3
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Mon May 9 11:32:51 2016 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Mon May 9 14:19:51 2016 +0200

    [cc2-qbe] Ensure correctness of basic blocks
    
    We have to take care of how basic blocks are built in QBE,
    so we have to ensure that all the basic blocks of the program
    are finalized with a jump of any type. We also need a label
    in the next statement of a branch, because in branches in QBE
    we have to use one label for true and another one for false.

diff --git a/cc2/arch/qbe/optm.c b/cc2/arch/qbe/optm.c
index 70ea0b0..e6a2329 100644
--- a/cc2/arch/qbe/optm.c
+++ b/cc2/arch/qbe/optm.c
_AT_@ -7,12 +7,32 @@
 Node *
 optm(Node *np)
 {
+ int op = np->op;
         Node *p, *dst, *next = np->next;
         Symbol *sym, *osym;
 
- switch (np->op) {
+ if (!next) {
+ /*
+ * In QBE we need at the end of a basic block
+ * a jump, so we have to ensure that the last
+ * statement of the function is a ret, a jmp
+ * or a branch. In the same way, QBE does
+ * not accept labels at the end of a function
+ * (ONOP is used for labels) so we have to add
+ * a ret there, and in the case of branches
+ * we need a label for the next statement
+ */
+ if (op == ONOP || op == OBRANCH || (op != ORET && op != OJMP)) {
+ p = newnode();
+ p->op = ORET;
+ addstmt(p, KEEPCUR);
+ }
+ next = np->next;
+ }
+
+ switch (op) {
         case ONOP:
- if (next && next->op == ONOP) {
+ if (next->op == ONOP) {
                         sym = np->u.sym;
                         osym = next->u.sym;
                         osym->id = sym->id;
_AT_@ -21,8 +41,13 @@ optm(Node *np)
                         return NULL;
                 }
                 break;
- case OJMP:
         case OBRANCH:
+ if (!next->label) {
+ sym = getsym(TMPSYM);
+ sym->kind = SLABEL;
+ next->label = sym;
+ }
+ case OJMP:
                 for (;;) {
                         dst = np->u.sym->u.stmt;
                         if (dst->op != OJMP)
Received on Mon May 09 2016 - 17:00:22 CEST

This archive was generated by hypermail 2.3.0 : Mon May 09 2016 - 17:12:21 CEST