aboutsummaryrefslogblamecommitdiff
path: root/ssa.c
blob: 39133f7f3ce20c99f319ce7cf48e60fa55e2ecd2 (plain) (tree)
1
2
3

                   
                   




































                                                             





                                                 















































                                                             





                                         



                                       
                 


                                    
                                 
                                    
                                 
                  






















                                               












































                                                         
 







                                                

                                           


                                                     





















































































































                                                                               
                 






                                                                       
                 



























                                                     
                       











                                                   

                    



























                                                      
                       






















































































































                                                                    
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ast.h"
#include "ssa.h"
#define NEW(type) ((type *)malloc(sizeof(type)))
#define DBLINK(from, to) ((from)->next = (to))->prev = (from)

static CGraph cfg;
static CBlock_t blks[MAX_BLOCK];
static int bcnt;        /* block counter */
static int tcnt;        /* temporary counter */
static int gbbase;

CBlock_t cblock_create() {
    CBlock_t cblk = NEW(CBlock);
    CInst_t dummy = NEW(CInst);
    dummy->prev = dummy;
    dummy->next = dummy;
    cblk->insts = dummy;
    cblk->next = NULL;
    cblk->id = (bcnt++) + gbbase;
    cblk->ref = 0;
    return cblk;
}

void cblock_append(CBlock_t cblk, CInst_t inst) {
    CInst_t head = cblk->insts;
    (inst->prev = head->prev)->next = inst;
    (inst->next = head)->prev = inst;
}

CInst_t cblock_getback(CBlock_t cblk) {
    return cblk->insts->prev;
}

int cblock_isempty(CBlock_t cblk) {
    return cblk->insts->prev == cblk->insts;
}

CVar_t ctmp_create(CType_t type) {
    static char buff[MAX_NAMELEN];
    sprintf(buff, "t%d", tcnt++);
    return cvar_create(strdup(buff), type, NULL);
}

void cfg_clear() {
    int i;
    for (i = 0; i < MAX_BLOCK; i++)
        if (cfg.head[i])
        {
            CEdge *p, *np;
            for (p = cfg.head[i]; p; p = np)
            {
                np = p->next;
                free(p);
            }
            cfg.head[i] = NULL;
        }
}

void cfg_add_edge(CBlock_t from, CBlock_t to) {
    int id = from->id;
    CEdge *e = NEW(CEdge);
    e->to = to;
    e->next = cfg.head[id];
    cfg.head[id] = e;
}

void copr_print(COpr *opr) {
    switch (opr->kind)
    {
        case VAR: 
        case TMP: fprintf(stderr, "%s", opr->info.var->name);
                  break;
        case IMM: fprintf(stderr, "%d", opr->info.imm);
                  break;
    }
}

void cinst_print(CInst_t inst) {
    switch (inst->op)
    {
        case MOVE:
            copr_print(&inst->dest);
            fprintf(stderr, " = ");
            copr_print(&inst->src1);
            break;
        case BEQZ:
            fprintf(stderr, "if not (");
            copr_print(&inst->src1);
            fprintf(stderr, ") goto _L");
            copr_print(&inst->dest);
            break;
        case BNEZ:
            fprintf(stderr, "if (");
            copr_print(&inst->src1);
            fprintf(stderr, ") goto _L");
            copr_print(&inst->dest);
            break;
        case GOTO:
            fprintf(stderr, "goto _L");
            copr_print(&inst->dest);
            break;
        case ARR:
            copr_print(&inst->dest);
            fprintf(stderr, " = ");
            copr_print(&inst->src1);
            fprintf(stderr, "[");
            copr_print(&inst->src2);
            fprintf(stderr, "]");
            break;
        default:
            {
                const char *op;
                switch (inst->op)
                {
                    case MUL: op = "*"; break;
                    case DIV: op = "/"; break;
                    case MOD: op = "%"; break;
                    case ADD: op = "+"; break;
                    case SUB: op = "-"; break;
                    case SHL: op = "<<"; break;
                    case SHR: op = ">>"; break;
                    case AND: op = "&"; break;
                    case XOR: op = "^"; break;
                    case OR: op = "|"; break;
                    default: ;
                }
                copr_print(&inst->dest);
                fprintf(stderr, " = ");
                copr_print(&inst->src1);
                fprintf(stderr, " %s ", op);
                copr_print(&inst->src2);
            }
    }
    fprintf(stderr, "\n");
}

void cblock_print(CBlock_t blk) {
    CInst_t p, sp = blk->insts;
    if (blk->ref)
        fprintf(stderr, "_L%d:\n", blk->id);
    for (p = sp->next; p != sp