?? 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 + -