?? eccsaving.cpp
字號:
/****************************************************/
/* 文件 ECCsaving.cpp */
/* */
/* 說明 TINY編譯器中間代碼的公共表達式優(yōu)化實現 */
/****************************************************/
#include "globals.h" /* 該頭文件定義全局類型和變量 */
#include "util.h" /*該頭文件定義了一些實用函數*/
#include "Eccsaving.h" /* 該頭文件聲明了公共表達式優(yōu)化界面函數*/
/* 值編碼表 */
ValuNum *valuNumT = NULL;
/* 可用表達式代碼表 */
UsableExpr *usableExprT = NULL;
/* 臨時變量的等價表 */
TempEqua *tempEquaT = NULL;
/*記錄值編碼*/
int Vnumber= 0;
/**********函數聲明***************/
int NewVN();
CodeFile *ECCsave();
void SaveInBlock(int i);
void EquaSubsti(CodeFile *code);
TempEqua *FindTempEqua(ArgRecord *arg);
int Process(CodeFile *code , int i);
ValuNum *SearchValuNum(ArgRecord *arg);
bool IsEqual(ArgRecord *arg1,ArgRecord *arg2);
void AppendValuNum(ArgRecord *arg , int Vcode);
CodeFile *FindECC(CodeKind codekind,int op1Code, int op2Code);
void AppendTempEqua(ArgRecord *arg1,ArgRecord *arg2);
MirrorCode *GenMirror(int op1,int op2,int result);
void AppendUsExpr(CodeFile *code,MirrorCode *mirror);
void SubstiVcode(ArgRecord *arg,int Vcode);
void DelUsExpr(ArgRecord *arg);
/********************************************************/
/* 函數名 NewVN */
/* 功 能 產生一個新的值編碼 */
/* 說 明 通過全局變量Vnumber加1,產生新的值編碼 */
/********************************************************/
int NewVN()
{ Vnumber++;
return (Vnumber);
}
/****************************************************/
/* 函數名 ECCsave */
/* 功 能 公共表達式優(yōu)化主函數 */
/* 說 明 循環(huán)對各個基本塊進行公共表達式優(yōu)化 */
/****************************************************/
/*注:考慮將blocknum用作局部變量,全局變量封裝不好*/
CodeFile *ECCsave()
{
ValuNum *freeVN = NULL;
UsableExpr *freeUE = NULL;
TempEqua *freeTE = NULL;
/*調用劃分基本塊函數*/
int blocknum = DivBaseBlock() ;
//PrintBaseBlock(blocknum);
//getchar( );
/*循環(huán)對每個基本塊進行公共表達式優(yōu)化*/
for (int i=0 ; i<blocknum ;i++)
{ /*基本塊入口處置值編碼表,
可用表達式表,臨時變量等價表為空*/
valuNumT = NULL;
usableExprT = NULL;
tempEquaT = NULL;
/*基本塊的ECC節(jié)省*/
SaveInBlock(i);
/*打印三個表*/
//printValuNum();
//printUsbleExpr();
//printTempEqua();
/*釋放此基本塊占用的表空間*/
while (valuNumT!=NULL)
{ freeVN = valuNumT ;
valuNumT = valuNumT->next;
free(freeVN);
}
while (usableExprT!=NULL)
{ freeUE = usableExprT;
usableExprT = usableExprT->next;
free(freeUE);
}
while(tempEquaT!=NULL)
{ freeTE = tempEquaT;
tempEquaT = tempEquaT->next;
free(freeTE);
}
}
/*返回優(yōu)化后的中間代碼*/
return(firstCode);
}
/****************************************************/
/* 函數名 SaveInBlock */
/* 功 能 基本塊優(yōu)化函數 */
/* 說 明 */
/****************************************************/
void SaveInBlock(int i)
{
int op1,op2,op3;
/*可用的表達式代碼*/
CodeFile *substiCode = NULL;
ValuNum *Entry = NULL;
/*指向基本塊第一條語句*/
CodeFile *currentCode = baseBlock[i];
CodeFile *formerCode = NULL;
CodeFile *laterCode = NULL;
/* 循環(huán)處理基本塊中的各條語句*/
while ((currentCode!=baseBlock[i+1])&&(currentCode!=NULL))
{
/*進行等價替換*/
EquaSubsti(currentCode);
switch(currentCode->codeR.codekind)
{ case ADD:
case SUB:
case MULT:
case DIV:
case LTC:
case EQC:
case AADD:
/*調用函數Process處理分量1,返回分量1的編碼*/
op1 = Process(currentCode ,1 );
/*調用函數Process處理分量2,返回分量2的編碼*/
op2 = Process(currentCode ,2 );
/*查找可用表達式代碼表*/
substiCode = FindECC(currentCode->codeR.codekind,op1,op2);
/*若找到,當前代碼可節(jié)省*/
if (substiCode!=NULL)
{
/*向臨時變量等價表中添加一項*/
AppendTempEqua(currentCode->codeR.arg3,substiCode->codeR.arg3);
/*刪除當前代碼*/
formerCode = currentCode->former;
laterCode = currentCode->next;
if (formerCode!=NULL)
formerCode->next = laterCode;
if (laterCode!=NULL)
laterCode->former = formerCode;
free(currentCode);
currentCode = formerCode;
}
else /*沒找到,代碼不可節(jié)省*/
{
/*為結果變量構造一個新的編碼,填入值編碼表*/
Vnumber++;
op3 = Vnumber;
AppendValuNum(currentCode->codeR.arg3,op3);
/*構造對應的映象碼*/
MirrorCode *mirror = GenMirror(op1,op2,op3);
/*當前代碼寫入可用表達式代碼表*/
AppendUsExpr(currentCode,mirror);
}
break;
case ASSIG:
/*Process函數處理賦值右部,返回編碼*/
op1 = Process(currentCode ,1 );
/*若是間接臨時變量,op1是地址碼;否則,是值碼*/
op2 = op1;
/*替換編碼表中賦值左部的值編碼*/
SubstiVcode(currentCode->codeR.arg2, op2);
/*刪除可用表達式代碼表中用到賦值左部值編碼的項*/
DelUsExpr(currentCode->codeR.arg2);
break;
default: break;
}
/*處理下一條代碼*/
currentCode = currentCode->next;
}
}
/****************************************************/
/* 函數名 EquaSubsti */
/* 功 能 利用臨時變量等價表對當前代碼進行等價替換 */
/* 說 明 */
/****************************************************/
void EquaSubsti(CodeFile *code)
{
TempEqua *Entry = NULL ;
if (code->codeR.arg1!=NULL)
/*若操作數1是臨時變量,且存在于臨時變量等價表中,則替換*/
if( code->codeR.arg1->form==AddrForm)
if(code->codeR.arg1->Attr.addr.dataLevel == -1)
{ Entry = FindTempEqua(code->codeR.arg1);
if (Entry!=NULL)
code->codeR.arg1 = Entry->arg2;
}
if (code->codeR.arg2!=NULL)
/*若操作數2是臨時變量,且存在于臨時變量等價表中,則替換*/
if( code->codeR.arg2->form==AddrForm)
if(code->codeR.arg2->Attr.addr.dataLevel == -1)
{ Entry = FindTempEqua(code->codeR.arg2);
if (Entry!=NULL)
code->codeR.arg2 = Entry->arg2;
}
}
/****************************************************/
/* 函數名 Process */
/* 功 能 處理操作分量,并返回對應的編碼 */
/* 說 明 若首次出現,則分配新編碼,填入編碼表中, */
/* 返回值取這個新的編碼;否則,根據是否間接 */
/* 變量,返回相應的值編碼或地址碼 */
/****************************************************/
int Process(CodeFile *code , int i)
{
ArgRecord *arg;
ValuNum *Entry = NULL ;
CodeKind codekind = code->codeR.codekind;
int opC ;
if (i==1)
arg = code->codeR.arg1;
else arg = code->codeR.arg2;
/*若操作數首次出現,則填入編碼表*/
Entry = SearchValuNum(arg);
if( Entry==NULL)
{ Vnumber++;
opC = Vnumber; /*op1記錄操作數1的值編碼*/
AppendValuNum(arg,opC);
}
else
{
/*間接臨時變量*/
if (Entry->access == indir)
/*用間接臨時變量的地址碼*/
if((codekind == AADD)||(codekind == ASSIG))
/*取地址碼*/
opC= Entry->codeInfo.twoCode.addrcode;
else /*否則,取值碼*/
opC = Entry->codeInfo.twoCode.valuecode;
/*非間接臨時變量*/
else opC = Entry->codeInfo.valueCode;
}
return (opC);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -