?? loopopti.cpp
字號:
/****************************************************/
/* 文件 loopOpti.cpp */
/* */
/* 說明 TINY編譯器中間代碼的循環不變式外提優化 */
/****************************************************/
#include "globals.h" /* 該頭文件定義全局類型和變量 */
#include "util.h" /*該頭文件定義了一些實用函數*/
#include "loopOpti.h" /* 該頭文件聲明了循環不變式優化界面函數*/
/*變量定值表,用變量的arg結構表示變量*/
ArgRecord *varTable[100];
int TotalNum = 0;
/*循環信息棧*/
LoopStack *loopTop = NULL;
bool loopStackEmpty;
/***************函數聲明********************/
CodeFile * LoopOpti();
void whileEntry(CodeFile *code);
void whileEnd(CodeFile *code);
void call(CodeFile *code);
void LoopOutside(CodeFile *entry);
int SearchTable(ArgRecord *arg , int head);
void DelItem(ArgRecord *arg, int head);
void AddTable(ArgRecord *arg);
void printVarTable();
/****************************************************/
/* 函數名 LoopOpti */
/* 功 能 循環不變式優化主函數 */
/* 說 明 */
/****************************************************/
CodeFile *LoopOpti()
{
/*初始化變量定值表*/
for (int i=0;i<100;i++)
varTable[i] = NULL;
/*從第一條代碼開始優化過程*/
CodeFile *currentCode = firstCode;
fprintf(listing,"\n>>Var def Table after each code:\n");
/*循環處理每條代碼,直到中間代碼結束*/
while (currentCode!=NULL)
{
switch(currentCode->codeR.codekind)
{ /*算術和關系操作*/
case AADD:
case ADD:
case SUB:
case MULT:
case DIV:
case LTC:
case EQC:
/*將被定值的變量名填入變量定值表中*/
AddTable(currentCode->codeR.arg3);
break;
/*賦值語句*/
case ASSIG:
/*將被定值的變量填入變量定值表中*/
AddTable(currentCode->codeR.arg2);
break;
/*循環入口*/
case WHILESTART:
whileEntry(currentCode);
break;
/*循環出口*/
case ENDWHILE:
whileEnd(currentCode);
break;
/*過程調用語句*/
case CALL:
call(currentCode);
break;
default : break;
}
/*調用函數輸出變量定值表,以現在處理完每條代碼后,
表的變化*/
printVarTable();
/*令指針指向下一條代碼*/
currentCode = currentCode->next;
}
return (firstCode);
}
/****************************************************/
/* 函數名 whileEntry */
/* 功 能 循環入口部分的處理函數 */
/* 說 明 */
/****************************************************/
void whileEntry(CodeFile *code)
{
LoopInfo *infoItem = (LoopInfo*)malloc(sizeof(LoopInfo));
/*外提標志初始化為可以外提標志1*/
infoItem->state = 1;
/*此循環在變量定值表的入口*/
infoItem->varDef = TotalNum;
/*循環入口指針*/
infoItem->whileEntry = code;
/*循環出口此處不能確定*/
//infoItem.whileEnd = NULL;
/*循環信息表壓棧*/
PushLoop(infoItem);
}
/****************************************************/
/* 函數名 call */
/* 功 能 遇到過程調用語句的特別處理 */
/* 說 明 所有包含此調用語句的循環都不能做不變式 */
/* 外提 */
/****************************************************/
void call(CodeFile *code)
{
/*所有打開著的循環均為不可外提狀態,是這些循環信息中的
State取0*/
LoopStack *Item = loopTop;
while (Item!=NULL)
{ Item->loopInfo->state = 0;
Item = Item->under;
}
}
/****************************************************/
/* 函數名 whileEnd */
/* 功 能 循環出口部分的處理函數 */
/* 說 明 */
/****************************************************/
void whileEnd(CodeFile *code)
{
/*循環信息棧的棧頂*/
LoopStack *Item = loopTop;
/*可以外提*/
if (Item->loopInfo->state == 1)
{
/*填寫循環出口位置指針*/
loopTop->loopInfo->whileEnd = code;
/*找到循環入口*/
CodeFile *entry = loopTop->loopInfo->whileEntry;
/*循環外提處理部分*/
LoopOutside(entry );
}
/*彈循環信息棧,此層循環處理結束*/
PopLoop();
}
/****************************************************/
/* 函數名 LoopOutside */
/* 功 能 循環外提處理函數 */
/* 說 明 */
/****************************************************/
void LoopOutside(CodeFile *entry)
{
/*外提的位置,為循環入口位置*/
CodeFile *place = entry;
/*當前處理代碼,注:跳過循環開始標號語句*/
CodeFile *code = entry->next;
/*取循環信息棧頂指針*/
LoopStack *Item = loopTop;
/*取得本層循環的出口位置*/
CodeFile *end = Item->loopInfo->whileEnd;
/*取得本層循環的變量信息表*/
int head = Item->loopInfo->varDef;
int present1, present2;
/*用于跳過內層循環*/
int Level = 0;
/*循環檢查每條代碼是否可以外提,直到此層循環結束*/
while (code != end )
{
switch(code->codeR.codekind)
{
case WHILESTART:
Level++; break;
case ENDWHILE:
Level--; break;
case ADD:
case SUB:
case MULT:
case AADD:
/*跳過內層循環*/
if (Level==0)
{
present1 = SearchTable(code->codeR.arg1,head);
present2 = SearchTable(code->codeR.arg2,head);
/*兩個分量都不在變量定值標號中,可以外提*/
if ((present1<0)&&(present2<0))
{ /*操作結果也是不變量,故若在表中,從表中刪除*/
DelItem(code->codeR.arg3, head);
/*外提*/
/*在當前位置,刪除此代碼*/
CodeFile *formerCode = code->former;
CodeFile *nextCode = code->next;
formerCode->next = nextCode;
nextCode->former = formerCode;
/*將代碼加入到應外提的位置*/
CodeFile *fplace = place->former;
fplace->next = code;
code->former = fplace;
code->next = place;
place->former = code;
/*回到當前位置處,準備處理下一條語句*/
code = formerCode;
}
else
/*否則,將變量定值加入當前變量定值表中*/
AddTable(code->codeR.arg3);
}
break;
default : break;
}
/*檢查下一條語句*/
code = code->next;
}
}
/****************************************************/
/* 函數名 SearchTable */
/* 功 能 循環變量定值表查找函數 */
/* 說 明 參數head指明了本層循環的變量定值在表中的 */
/* 起始位置,arg表示要查找的變量,返回變量 */
/* 在表中的位置,若不存在返回值為-1 */
/****************************************************/
int SearchTable(ArgRecord *arg , int head)
{
/*初始化為負數,不再表中*/
int present = -1 ;
if (arg->form ==AddrForm)
{
int level = arg->Attr.addr.dataLevel;
int off = arg->Attr.addr.dataOff;
/*注:臨時變量和源變量都可以通過比較層數和偏移看是否存在
于表中*/
for (int i = head; i<TotalNum; i++)
if ((varTable[i]->Attr.addr.dataLevel == level)
&&(varTable[i]->Attr.addr.dataOff == off))
{ present = i;
break;
}
}
return(present);
}
/****************************************************/
/* 函數名 DelItem */
/* 功 能 刪除變量定值表中此項 */
/* 說 明 */
/****************************************************/
void DelItem(ArgRecord *arg, int head)
{
/*調用函數查找變量定值表*/
int present = SearchTable(arg , head);
/*若在表中,則刪除*/
if (present!=-1)
{ for (int i=present;i<TotalNum ; i++)
varTable[i] =varTable[i+1];
TotalNum--;
}
}
/****************************************************/
/* 函數名 AddTable */
/* 功 能 將被定值的變量填入變量定值表 */
/* 說 明 */
/****************************************************/
void AddTable(ArgRecord *arg)
{
/*若不在循環中,則從頭查表,以免表中重復填入相同的變量*/
int head = 0;
/*若在循環中,則只要在當前循環層沒有重復定義即可*/
if (loopTop!=NULL)
head = loopTop->loopInfo->varDef;
int present = SearchTable(arg , head);
/*表中沒有,則添加*/
if (present==-1)
varTable[TotalNum++] = arg;
}
/****************************************************/
/* 函數名 printVarTable */
/* 功 能 輸出變量定值表 */
/* 說 明 */
/****************************************************/
void printVarTable()
{
fprintf(listing,">>");
/*輸出變量定值表*/
for (int i=0;i<TotalNum;i++)
{
if (varTable[i]!=NULL)
{ if (varTable[i]->Attr.addr.dataLevel== -1)
{ fprintf(listing, "temp");
fprintf(listing,"%d",varTable[i]->Attr.addr.dataOff);
fprintf(listing," ");
}
else
fprintf(listing, "%s ",varTable[i]->Attr.addr.name);
}
}
fprintf(listing,"\n");
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -