⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wsopt.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
字号:
/* ====================================================================  * The Kannel Software License, Version 1.0  *  * Copyright (c) 2001-2004 Kannel Group   * Copyright (c) 1998-2001 WapIT Ltd.    * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  *  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  *  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in  *    the documentation and/or other materials provided with the  *    distribution.  *  * 3. The end-user documentation included with the redistribution,  *    if any, must include the following acknowledgment:  *       "This product includes software developed by the  *        Kannel Group (http://www.kannel.org/)."  *    Alternately, this acknowledgment may appear in the software itself,  *    if and wherever such third-party acknowledgments normally appear.  *  * 4. The names "Kannel" and "Kannel Group" must not be used to  *    endorse or promote products derived from this software without  *    prior written permission. For written permission, please   *    contact org@kannel.org.  *  * 5. Products derived from this software may not be called "Kannel",  *    nor may "Kannel" appear in their name, without prior written  *    permission of the Kannel Group.  *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,   * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * ====================================================================  *  * This software consists of voluntary contributions made by many  * individuals on behalf of the Kannel Group.  For more information on   * the Kannel Group, please see <http://www.kannel.org/>.  *  * Portions of this software are based upon software originally written at   * WapIT Ltd., Helsinki, Finland for the Kannel project.   */ /* * * wsopt.c * * Author: Markku Rossi <mtr@iki.fi> * * Copyright (c) 1999-2000 WAPIT OY LTD. *		 All rights reserved. * * Optimizations for the WMLScript symbolic assembler. * */#include "wsint.h"#include "wsasm.h"/* TODO: liveness analyzation *//* TODO: jumps to return or return_es *//* TODO: remove empty labels (helps peephole opt) *//* TODO: i++; becomes "load, incr, pop", optimize to just incr. *//* TODO: { const; tjump } -> { jump or nothing } *//********************* Optimization functions ***************************/static WsBool opt_jumps_to_jumps(WsCompilerPtr compiler){    WsAsmIns *i;    WsBool change = WS_TRUE;    unsigned int count = 0;    ws_info(compiler, "optimize: jumps to jumps");    while (change) {        count++;        change = WS_FALSE;        for (i = compiler->asm_head; i; i = i->next) {            WsAsmIns * j;            if (!WS_ASM_P_BRANCH(i))                continue;            /* Find the next instruction following the label. */            for (j = i->ws_label; j && j->type == WS_ASM_P_LABEL; j = j->next)                ;            if (j == NULL || j->type != WS_ASM_P_JUMP)                /* Can't optimize this case. */                continue;            /* We can optimize the jump `i' directly to the label of                      `j'.  We must remember to update the reference counts                      too. */            i->ws_label->ws_label_refcount--;            j->ws_label->ws_label_refcount++;            i->ws_label = j->ws_label;            change = WS_TRUE;        }    }    return count > 1;}static WsBool opt_jumps_to_next_instruction(WsCompilerPtr compiler){    WsAsmIns *i;    WsBool change = WS_FALSE;    ws_info(compiler, "optimize: jumps to next instruction");    for (i = compiler->asm_head; i; i = i->next) {        WsAsmIns * j;        if (i->type != WS_ASM_P_JUMP)            continue;        for (j = i->next;             j && j->type == WS_ASM_P_LABEL && i->ws_label != j;             j = j->next)            ;        if (i->ws_label != j)            /* Nop. */            continue;        /* Remove the jump instruction `i'. */        change = WS_TRUE;        i->ws_label->ws_label_refcount--;        if (i->next)            i->next->prev = i->prev;        else            compiler->asm_tail = i->prev;        if (i->prev)            i->prev->next = i->next;        else            compiler->asm_head = i->next;        /* Continue from the label `j'. */        i = j;    }    return change;}static WsBool opt_dead_code(WsCompilerPtr compiler){    WsBool change = WS_FALSE;    WsAsmIns *i;    ws_info(compiler, "optimize: dead code");    for (i = compiler->asm_head; i; i = i->next) {        WsAsmIns * j;        if (!(i->type == WS_ASM_P_JUMP ||              i->type == WS_ASM_RETURN ||              i->type == WS_ASM_RETURN_ES))            continue;        /* Skip until the next referenced label is found. */        for (j = i->next;             j && (j->type != WS_ASM_P_LABEL || j->ws_label_refcount == 0);             j = j->next) {            /* Update label reference counts in the deleted block. */            if (WS_ASM_P_BRANCH(j))                j->ws_label->ws_label_refcount--;        }        if (j == i->next)            /* Nothing to delete. */            continue;        /* Delete everything between `i' and `j'. */        i->next = j;        if (j)            j->prev = i;        else            compiler->asm_tail = i;        change = WS_TRUE;    }    return change;}static WsBool opt_peephole(WsCompilerPtr compiler){    WsBool change = WS_FALSE;    WsAsmIns *i, *i2, *prev;    WsAsmIns *new;    ws_info(compiler, "optimize: peephole");    prev = NULL;    i = compiler->asm_head;    while (i) {        /* Two instructions wide peephole. */        if (i->next) {            i2 = i->next;            /*             * {load*,const*}	=>	-             * pop             */            if (i2->type == WS_ASM_POP                && (i->type == WS_ASM_P_LOAD_VAR                    || i->type == WS_ASM_P_LOAD_CONST                    || i->type == WS_ASM_CONST_0                    || i->type == WS_ASM_CONST_1                    || i->type == WS_ASM_CONST_M1                    || i->type == WS_ASM_CONST_ES                    || i->type == WS_ASM_CONST_INVALID                    || i->type == WS_ASM_CONST_TRUE                    || i->type == WS_ASM_CONST_FALSE)) {                /* Remove both instructions. */                change = WS_TRUE;                if (prev)                    prev->next = i2->next;                else                    compiler->asm_head = i2->next;                if (i2->next)                    i2->next->prev = prev;                else                    compiler->asm_tail = prev;                i = i2->next;                continue;            }            /*             * const_es           =>      return_es             * return             */            if (i2->type == WS_ASM_RETURN && i->type == WS_ASM_CONST_ES) {                /* Replace with WS_ASM_RETURN_ES */                new = ws_asm_ins(compiler, i->line, WS_ASM_RETURN_ES);                if (new) {                    change = WS_TRUE;                    if (prev)                        prev->next = new;                    else                        compiler->asm_head = new;                    new->prev = prev;                    new->next = i2->next;                    if (new->next)                        new->next->prev = new;                    else                        compiler->asm_tail = new;                    i = new;                    continue;                }            }        }        /* Move forward. */        prev = i;        i = i->next;    }    /* The interpreter will by default return the empty string if a     * function ends without a return statement, so returning the     * empty string at the end of a function is never useful. */    if (compiler->asm_tail && compiler->asm_tail->type == WS_ASM_RETURN_ES) {        compiler->asm_tail = compiler->asm_tail->prev;        if (compiler->asm_tail == NULL)            compiler->asm_head = NULL;        else            compiler->asm_tail->next = NULL;    }    return change;}/* * Remove conversions that are followed by an opcode that does * that conversion automatically anyway. */static WsBool opt_conv(WsCompilerPtr compiler){    WsBool change = WS_FALSE;    WsAsmIns *i, *next, *prev;    ws_info(compiler, "optimize: peephole");    prev = NULL;    i = compiler->asm_head;    while (i) {        if (i->type == WS_ASM_TOBOOL) {	    next = i->next;            /* Skip labels.  They're not going to affect which instruction             * gets executed after this TOBOOL. */  	    while (next != NULL && next->type == WS_ASM_P_LABEL)	        next = next->next;   	    if (next != NULL &&                (next->type == WS_ASM_P_TJUMP ||                 next->type == WS_ASM_NOT ||	         next->type == WS_ASM_SCAND ||	         next->type == WS_ASM_SCOR ||	         next->type == WS_ASM_TOBOOL ||	         next->type == WS_ASM_POP)) {	        /* The next instruction will automatically convert its	         * operand to boolean, or does not care about its operand	         * (POP), so the TOBOOL is not necessary.  Delete it.  */	        change = WS_TRUE;	        /* Use i->next here because next might have been incremented	         * past a label, which we do not want to delete. */	        if (prev)	    	    prev->next = i->next;	        else	    	    compiler->asm_head = i->next;	        if (i->next)                    i->next->prev = prev;                else                    compiler->asm_tail = prev;	    }        }	prev = i;	i = i->next;    }    return change;}/********************* Global entry point *******************************/void ws_asm_optimize(WsCompilerPtr compiler){    WsBool change = WS_TRUE;    /* While we manage to change the assembler, perform the requested       optimizations. */    while (change) {        change = WS_FALSE;	/* Useless conversions */	if (!compiler->params.no_opt_conv && opt_conv(compiler))	    change = WS_TRUE;        /* Peephole. */        if (!compiler->params.no_opt_peephole && opt_peephole(compiler))            change = WS_TRUE;        /* Jumps to jump instructions. */        if (!compiler->params.no_opt_jumps_to_jumps            && opt_jumps_to_jumps(compiler))            change = WS_TRUE;        /* Jumps to the next instruction. */        if (!compiler->params.no_opt_jumps_to_next_instruction            && opt_jumps_to_next_instruction(compiler))            change = WS_TRUE;        /* Unreachable code. */        if (!compiler->params.no_opt_dead_code && opt_dead_code(compiler))            change = WS_TRUE;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -