📄 eccsaving.cpp
字号:
/****************************************************/
/* 函数名 FindTempEqua */
/* 功 能 查找临时变量等价表 */
/* 说 明 */
/****************************************************/
TempEqua *FindTempEqua(ArgRecord *arg)
{
TempEqua *Item = tempEquaT ;
while (Item!=NULL)
{ /*注:因为是临时变量,故这里可以直接使用指针比较
而一般变量则不行,因为同一个变量可能会产生
多个内容相同的ARG结构,根据中间代码生成时的
处理手段*/
if (Item->arg1 == arg)
break;
Item = Item->next;
}
return (Item);
}
/****************************************************/
/* 函数名 SearchValuNum */
/* 功 能 查找编码表 */
/* 说 明 若存在于编码表中返回入口地址;否则返回空 */
/****************************************************/
ValuNum *SearchValuNum(ArgRecord *arg)
{
bool equal = false;
/*指向编码表*/
ValuNum *Item = valuNumT;
while (Item != NULL)
{ /*比较是否有相同的变量*/
equal = IsEqual(Item->arg,arg);
if (equal)
break;
Item = Item->next;
}
return(Item);
}
/****************************************************/
/* 函数名 IsEqual */
/* 功 能 判断两个ARG结构是否相同 */
/* 说 明 这里运算分量没有标号,故只考虑了常量类 */
/* 和地址类ARG结构 */
/****************************************************/
bool IsEqual(ArgRecord *arg1,ArgRecord *arg2)
{
bool equal = false ;
/*注:应比较ARG结构内容,不能比较指针,因为一个相同的变量
可能会产生多个相同的ARG结构,由不同的指针指向,这是
由中间代码生成时的处理策略决定的*/
if (arg1->form == arg2->form)
switch(arg1->form)
{/*常数类:值相等则等价*/
case ValueForm :
if (arg1->Attr.value == arg2->Attr.value)
equal = true ;
break;
/*地址类:层数,偏移,访问方式都相等时等价*/
case AddrForm:
if ((arg1->Attr.addr.dataLevel == arg2->Attr.addr.dataLevel)
&&(arg1->Attr.addr.dataOff == arg2->Attr.addr.dataOff)
&&(arg1->Attr.addr.access == arg2->Attr.addr.access))
equal = true ;
break;
default :break;
}
return (equal);
}
/****************************************************/
/* 函数名 AppendValuNum */
/* 功 能 当前变量及值写入值编码表中 */
/* 说 明 申请一个新节点,根据变量是否为间接临时变 */
/* 填写不同的内容,并联入表中 */
/****************************************************/
void AppendValuNum(ArgRecord *arg , int Vcode)
{
/*最后一个节点指针*/
ValuNum *last ;
/*申请一个新的值编码表的节点,并填写内容*/
ValuNum *newItem = (ValuNum *)malloc(sizeof(ValuNum));
newItem->arg = arg ;
newItem->next = NULL;
/*若是间接临时变量*/
if (arg->form == AddrForm )
if (arg->Attr.addr.dataLevel == -1)
if (arg->Attr.addr.access == indir )
{
newItem->access = indir ;
newItem->codeInfo.twoCode.valuecode = Vcode;
newItem->codeInfo.twoCode.addrcode = Vcode;
goto L1;
}
/*其余情况为:非间接临时变量*/
newItem->access = dir;
newItem->codeInfo.valueCode = Vcode;
L1: /*节点联入值编码表中*/
if (valuNumT == NULL)
valuNumT = newItem;
else
{ last = valuNumT ;
while (last->next!=NULL)
last = last->next;
last->next = newItem;
}
}
/****************************************************/
/* 函数名 FindECC */
/* 功 能 判断可用表达式表中是否有可用的表达式代码 */
/* 说 明 若有,返回用于替换的中间代码指针 */
/* 否则,返回为空 */
/****************************************************/
CodeFile *FindECC(CodeKind codekind,int op1Code, int op2Code)
{
CodeFile * substiCode =NULL;
UsableExpr *currentItem = usableExprT;
while ((currentItem != NULL)&&(substiCode==NULL))
{ /*语句类别相同*/
if (currentItem->code->codeR.codekind == codekind )
/*对应分量编码都相同,可替换*/
if ((currentItem->mirrorC->op1== op1Code)&&(currentItem->mirrorC->op2 == op2Code))
substiCode = currentItem->code;
else
/*可交换运算符,分量编码交叉相同,也可替换*/
if ((codekind ==ADD)||(codekind == MULT))
if ((currentItem->mirrorC->op1== op2Code)&&(currentItem->mirrorC->op1 == op2Code))
substiCode = currentItem->code;
currentItem = currentItem->next;
}
return (substiCode);
}
/****************************************************/
/* 函数名 AppendTempEqua */
/* 功 能 将两个等价的临时变量写入临时变量等价表中 */
/* 说 明 表示第一项可以被第二项替换 */
/****************************************************/
void AppendTempEqua(ArgRecord *arg1,ArgRecord *arg2)
{
/*最后一个节点指针*/
TempEqua *last ;
/*申请一个新的临时变量等价表的节点,并填写内容*/
TempEqua *newItem = (TempEqua *)malloc(sizeof(TempEqua));
newItem->arg1 = arg1;
newItem->arg2 = arg2;
newItem->next = NULL;
/*节点联入临时变量等价表中*/
if (tempEquaT == NULL)
tempEquaT = newItem;
else
{ last = tempEquaT ;
while (last->next!=NULL)
last = last->next;
last->next = newItem;
}
}
/****************************************************/
/* 函数名 GenMirror */
/* 功 能 构造映象码 */
/* 说 明 */
/****************************************************/
MirrorCode * GenMirror(int op1,int op2,int result)
{
MirrorCode *mirror = (MirrorCode *) malloc (sizeof(MirrorCode));
mirror->op1 = op1;
mirror->op2 = op2;
mirror->result = result ;
return (mirror);
}
/****************************************************/
/* 函数名 AppendUsExpr */
/* 功 能 将中间代码和相应的映象码写可用表达式表中 */
/* 说 明 */
/****************************************************/
void AppendUsExpr(CodeFile *code,MirrorCode *mirror)
{
UsableExpr *last ;
UsableExpr *newItem = (UsableExpr *)malloc(sizeof(UsableExpr));
newItem->code = code;
newItem->mirrorC = mirror;
newItem->next = NULL;
if (usableExprT==NULL)
usableExprT = newItem ;
else
{ last = usableExprT ;
while (last->next!=NULL)
last = last->next ;
last->next = newItem;
}
}
/****************************************************/
/* 函数名 SubstiVcode */
/* 功 能 将当前变量,及其值编码写入编码表 */
/* 说 明 若变量首次出现,则添加一项;否则,将表中 */
/* 此变量的值编码替换为新的值编码 */
/****************************************************/
void SubstiVcode(ArgRecord *arg,int Vcode)
{
ValuNum *Entry = SearchValuNum(arg );
/*若操作数首次出现,则填入编码表*/
if( Entry==NULL)
AppendValuNum(arg , Vcode);
else
{
/*间接临时变量*/
if (Entry->access == indir)
Entry->codeInfo.twoCode.valuecode = Vcode;
/*非间接临时变量*/
else Entry->codeInfo.valueCode = Vcode;
}
}
/****************************************************/
/* 函数名 DelUsExpr */
/* 功 能 将可用表达式代码表中用到arg的值编码的项 */
/* 删除 */
/* 说 明 */
/****************************************************/
void DelUsExpr(ArgRecord *arg)
{
bool same = false ;
UsableExpr *Item = usableExprT;
UsableExpr *former = Item ;
while (Item!=NULL)
{ /*因为AADD用的是地址码,所以不考虑*/
if (Item->code->codeR.codekind!=AADD)
{ if (Item->code->codeR.arg1==arg)
same = true;
else if (Item->code->codeR.arg2 == arg)
same = true;
else if (Item->code->codeR.arg3 == arg)
same = true;
if (same)
{ /*删除这个可用表达式项*/
if (Item == usableExprT)
{ usableExprT = Item->next;
free(Item);
former = Item = usableExprT;
}
else
{ former->next = Item->next;
free(Item);
Item = former->next;
}
/*跳到下一次循环开始处*/
continue;
}
}
/*指针后移,比较下一个节点*/
former = Item;
Item = Item->next;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -