📄 consopti.cpp
字号:
/****************************************************/
/* 文件 consOpti.cpp */
/* */
/* 说明 TINY编译器中间代码的常量表达式优化实现 */
/****************************************************/
#include "globals.h" /* 该头文件定义全局类型和变量 */
#include "util.h" /*该头文件定义了一些实用函数*/
#include "ConsOpti.h" /* 该头文件声明了常表达式优化界面函数*/
/*常量定值表*/
ConstDefT *table = NULL;
/**********函数声明************/
void OptiBlock(int i) ;
bool ArithC( CodeFile *code) ;
void SubstiArg(CodeFile *code,int i);
bool FindConstT(ArgRecord *arg, ConstDefT **Entry);
void AppendTable(ArgRecord *arg , int result);
void DelConst(ArgRecord *arg);
void printConstTable(int i);
/****************************************************/
/* 函数名 ConstOptimize */
/* 功 能 常表达式优化主函数 */
/* 说 明 循环对各个基本块进行常表达式优化 */
/****************************************************/
CodeFile *ConstOptimize()
{
/*用于释放空间*/
ConstDefT * freeTemp = NULL;
/*调用划分基本块函数*/
int blocknum = DivBaseBlock();
//PrintBaseBlock(blocknum);
//getchar( );
/*循环对每个基本块进行常表达式优化*/
for (int i=0 ; i<blocknum ;i++)
{ /*基本块入口处置常量定值表为空*/
table = NULL;
/*基本块的常表达式优化*/
OptiBlock(i);
/*释放此基本块的常量定值表空间*/
while (table!=NULL)
{ freeTemp = table;
table = freeTemp->next;
free(freeTemp);
}
}
/*返回优化后的中间代码*/
return(firstCode);
}
/****************************************************/
/* 函数名 OptiBlock */
/* 功 能 对一个基本块进行常表达式优化 */
/* 说 明 */
/****************************************************/
void OptiBlock(int i)
{
bool delCode ;
/*指向基本块第一条语句*/
CodeFile *currentCode = baseBlock[i] ;
CodeFile *formerCode = NULL;
CodeFile *laterCode = NULL;
ArgRecord *arg1 = NULL ;
ArgRecord *arg2 = NULL ;
/*循环处理每条代码,直到当前基本块结束*/
while ((currentCode!=baseBlock[i+1])&&(currentCode!=NULL))
{
switch(currentCode->codeR.codekind)
{ /*算术和关系操作*/
case ADD:
case SUB:
case MULT:
case DIV:
case LTC:
case EQC:
/*调用算术和关系运算处理函数*/
delCode = ArithC(currentCode);
/*删除标识为真时,删除当前多元式*/
if (delCode)
{ formerCode = currentCode->former;
laterCode = currentCode->next;
if (formerCode!=NULL)
formerCode->next = laterCode;
if (laterCode!=NULL)
laterCode->former = formerCode;
free(currentCode);
currentCode = formerCode ;
}
break;
/*赋值语句*/
case ASSIG:
/*对第一个ARG结构进行值替换*/
SubstiArg(currentCode,1);
arg1 = currentCode->codeR.arg1;
arg2 = currentCode->codeR.arg2;
/*若是常数结构,则将常量定值加入常量定值表*/
if (arg1->form==ValueForm)
AppendTable(arg2,arg1->Attr.value);
else /*删除表中含有此变量的定值*/
DelConst(arg2);
break;
case JUMP0:
case WRITEC:
/*对第一个ARG结构进行值替换*/
SubstiArg(currentCode,1);
break;
case AADD:
/*对第二个ARG结构进行值替换*/
SubstiArg(currentCode,2);
break;
default : break;
}
/*调用函数输出当前常量定值表*/
printConstTable(i); /*对应于每条代码,常量定值表的变化情况*/
/*令指针指向下一条代码*/
currentCode = currentCode->next;
}
}
/****************************************************/
/* 函数名 ArithC */
/* 功 能 处理算术操作和关系比较操作 */
/* 说 明 对运算分量1和运算分量2进行值替换,若都是 */
/* 常数,将结果写入常量定值表,并置四元式 */
/* 删除标志为真 */
/****************************************************/
bool ArithC (CodeFile *code)
{
bool delCode = false;
int value1,value2,result;
/*对分量1进行值替换*/
SubstiArg(code,1);
ArgRecord *arg1 = code->codeR.arg1;
/*对分量2进行值替换*/
SubstiArg(code,2);
ArgRecord *arg2 = code->codeR.arg2;
CodeKind codekind =code->codeR.codekind;
ArgRecord *arg3 = code->codeR.arg3;
/*操作分量都是常数*/
if ( (arg1->form==ValueForm) && (arg2->form==ValueForm))
{ value1 = arg1->Attr.value;
value2 = arg2->Attr.value;
switch( codekind)
{ case ADD: result = value1+value2; break;
case SUB: result = value1-value2; break;
case MULT: result = value1*value2; break;
case DIV: result = value1/value2; break;
case LTC: if (value1<value2)
result = 1;
else result = 0;
break;
case EQC: if (value1==value2)
result = 1;
else result = 0;
break;
default: break;
}
/*操作结果写入常量定值表*/
AppendTable( arg3 ,result);
/*当前多元式应删除*/
delCode = true;
}
return (delCode);
}
/****************************************************/
/* 函数名 SubstiArg */
/* 功 能 对一个ARG结构进行值替换 */
/* 说 明 参数i指出对中间代码的哪个ARG结构进行替换 */
/****************************************************/
void SubstiArg(CodeFile *code,int i)
{
ConstDefT *Entry = NULL ;
ArgRecord *arg = NULL;
ArgRecord *newArg = NULL;
if (1==i)
arg = code->codeR.arg1;
else arg = code->codeR.arg2;
/*若ARG结构是地址类,且常量定值表中有定值,则值替换*/
if ( arg->form ==AddrForm)
{
bool constflag = FindConstT(arg,&Entry);
if (constflag==true)
{ /*创建一个值的ARG结构,替换原有的ARG结构*/
newArg = (ArgRecord *)malloc(sizeof(ArgRecord));
newArg->form = ValueForm ;
newArg->Attr.value = Entry->constValue;
if (1==i)
code->codeR.arg1 = newArg;
else code->codeR.arg2 = newArg;
}
}
}
/****************************************************/
/* 函数名 FindConstT */
/* 功 能 在常量定值表中查找当前变量是否有定值 */
/* 说 明 输入为变量的ARG结构,根据变量是临时变量 */
/* 还是一般标识符变量,分别处理 */
/****************************************************/
bool FindConstT(ArgRecord *arg, ConstDefT **Entry)
{
bool present = false;
int level = arg->Attr.addr.dataLevel;
int off = arg->Attr.addr.dataOff;
ConstDefT *t =table;
while((t != NULL)&&(present==false))
{
if ((t->variable->Attr.addr.dataLevel == level)
&&(t->variable->Attr.addr.dataOff ==off))
{ present = true;
(*Entry) = t ;
}
t = t->next;
}
return(present);
}
/****************************************************/
/* 函数名 AppendTable */
/* 功 能 将变量和其常量值写入常量定值表 */
/* 说 明 创建一个新的节点,填写常量定值内容,并连 */
/* 入表中 */
/****************************************************/
void AppendTable(ArgRecord *arg , int result)
{
ConstDefT *last = table;
ConstDefT *current = table;
ConstDefT *Entry = NULL ;
/*查找,若已存在此变量,则改变其值*/
bool present = FindConstT(arg, &Entry) ;
if ( present )
Entry->constValue = result ;
else
{ /*否则,创建一个新的节点*/
ConstDefT *newConst = (ConstDefT *) malloc (sizeof(ConstDefT));
newConst->former = NULL ;
newConst->next = NULL;
newConst->constValue = result ;
newConst->variable = arg;
/*当前节点加入常量定值表中*/
if (table==NULL)
table = newConst ;
else
{ while (last->next != NULL)
last = last->next;
last->next = newConst ;
newConst->former = last ;
}
}
}
/****************************************************/
/* 函数名 DelConst */
/* 功 能 删除一个常量定值 */
/* 说 明 若存在,则从常量定值表中删除,否则结束 */
/****************************************************/
void DelConst(ArgRecord *arg)
{
ConstDefT *Entry = NULL;
ConstDefT *former = NULL;
ConstDefT *later = NULL;
/*查找变量,若存在则删除;否则,结束*/
bool present = FindConstT(arg, &Entry) ;
if ( present )
{ former = Entry->former;
later = Entry->next;
former->next = later;
later->former = former;
free(Entry);
}
}
/****************************************************/
/* 函数名 printConstTalbe */
/* 功 能 输出常量定值表 */
/* 说 明 */
/****************************************************/
void printConstTable(int i)
{
/*输出当前常量定值表*/
ConstDefT *print = table;
printf("%d%s",i,": ");
while (print!=NULL)
{
printf("(");
if (print->variable->Attr.addr.dataLevel!=-1)
printf(print->variable->Attr.addr.name);
else
{printf("temp");
printf("%d",print->variable->Attr.addr.dataOff);
}
printf(",");
printf("%d",print->constValue);
printf(")");
printf(" ");
print=print->next;
}
printf("\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -