[최적화] NOP 지령 삭제

제어 문장의 명령 생 성 과정 에서 문 구 는 외부 명령 구 조 를 알 수 없고 섣 불리 문 구 를 외부 명령 으로 지정 할 수 없 기 때문에 NOP 명령 을 사용 하여 이러한 도약 을 완화 시 켰 다. 그러나 모든 명령 생 성 이 끝 난 후에 점프 명령 은 상하 문 에 따라 정확 한 목 표를 선택 할 수 있다. 그러면 NOP 명령 은 성능 에 영향 을 주 는 불필요 한 명령 일 뿐이다. 토끼 가 죽 고 개가 요리 하 는 원칙 에 따라 지금 은 이 명령 들 을 없앤다.
static void cleanNop(struct List* instructions);

구체 적 인 방법 은 모든 것 을 위 한 것 이다. NOP 명령 어 기록 후 첫 번 째 비 NOP 명령, 그리고 명령 시퀀스 를 스 캔 하여 목 표를 다시 정 한 다음 에 모든 것 을 삭제 합 니 다. NOP 명령. 현재 명령 데이터 구조 에 색인 도 메 인 을 추가 합 니 다.
/*    index   */
#define memberAbstractInstruction \
    int segOffset;                \
    int index;                    \
    InstructionCode code; /*******/
struct AbstractInstruction {
    memberAbstractInstruction
};

옳 고 그 름 NOP 명령, 색인 필드 는 자신의 위치 색인 과 같 습 니 다. NOP 명령 의 색인 도 메 인 은 이 명령 이후 첫 번 째 비 와 같 습 니 다. NOP 명령 의 색인.
전체 명령 시퀀스 를 역방향 으로 옮 겨 다 니 며 색인 값 을 계산 합 니 다.
    int index = instructions->count(instructions) - 1;
    int lastOpInd;
    struct AbstractInstruction* ins;
    for (; index >=0; --index) {
        ins = (struct AbstractInstruction*)
              (instructions->elementAt(instructions, index));
        if (NOP != ins->code) {
            lastOpInd = index;
        }
        ins->index = lastOpInd;
    }

모든 점프 명령 을 스 캔 하고 다시 지정 합 니 다.
    struct Iterator* iterator;
    for_each (iterator, instructions) {
        ins = (struct AbstractInstruction*)(iterator->current(iterator));
        if (isJump(ins->code)) {
            struct JumpInstruction* jmp = (struct JumpInstruction*)ins;
            jmp->targetIns = instructions->elementAt(instructions,
                                                     jmp->targetIns->index);
        }
    }

삭제 NOP 지령
    for_each (iterator, instructions) {
        if (NOP == ((struct AbstractInstruction*)
                    (iterator->current(iterator)))->code) {
            revert(iterator->current(iterator));
            iterator->remove(iterator);
        }
    }

 
현재 수정 버 전에 서 출력 명령 의 코드 가 새 파일 로 옮 겨 져 Jerry - copiler. c 의 혼란 정 도 를 줄 였 습 니 다.
void fakeDefaultAnalyserConsumeNT(void* self, struct AbstractSyntaxNode* node)
{
    if (NULL == node) {
        return;
    }

    node = (struct AbstractSyntaxNode*)newBasicBlockNode(node);
    initStack(&loopStack);
    initialSymTabManager();
    struct List* insList = node->createInstruction(node);
    node->delNode(node);
    finalizeSymTabManager();
    loopStack.finalize(&loopStack);
    if (isFailed()) {
        while (0 != insList->count(insList)) {
            revert(insList->popElementAt(insList, 0));
        }
        cresult = ERROR_IN_SRC;
        return;
    }

    struct NoParamInstruction* endProg = (struct NoParamInstruction*)
                                    allocate(sizeof(struct NoParamInstruction));
    endProg->code = END_PROGRAM;
    insList->addTo(insList, endProg, insList->count(insList));
    /*         ,    writeInstruction       
       instruction-process.cpp / instruction-process.h */
    ErrMsg err = processIns(insList, treeout);
    if (NULL != err) {
        fputs(err, stderr);
        cresult = IO_ERROR;
    }
    insList->finalize(insList);
}

 
컴 파일 러 / 해석 기 구 조 는 여기 서 끝 납 니 다. 제 리 를 고 칠 수도 있 지만 장담 할 수 없습니다. 하 ~

좋은 웹페이지 즐겨찾기