?? emit-rtl.c
字號(hào):
{ first_insn = first; last_insn = last;}/* Go through all the RTL insn bodies and copy any invalid shared structure. It does not work to do this twice, because the mark bits set here are not cleared afterwards. */static int unshare_copies = 0; /* Count rtx's that were copied. */static rtx copy_rtx_if_shared ();voidunshare_all_rtl (insn) register rtx insn;{ extern rtx stack_slot_list; for (; insn; insn = NEXT_INSN (insn)) if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN) { PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn)); REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn)); LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn)); } /* Make sure the addresses of stack slots are not shared with anything in the insn chain. That could happen if the stack slot is referenced only by its address. */ copy_rtx_if_shared (stack_slot_list);}/* Mark ORIG as in use, and return a copy of it if it was already in use. Recursively does the same for subexpressions. */static rtxcopy_rtx_if_shared (orig) rtx orig;{ register rtx x = orig; register int i; register enum rtx_code code; register char *format_ptr; int copied = 0; if (x == 0) return 0; code = GET_CODE (x); /* These types may be freely shared. */ switch (code) { case REG: case QUEUED: case CONST_INT: case CONST_DOUBLE: case SYMBOL_REF: case CODE_LABEL: case PC: case CC0: return x; case INSN: case JUMP_INSN: case CALL_INSN: case NOTE: case LABEL_REF: case BARRIER: /* The chain of insns is not being copied. */ return x; case MEM: /* A MEM is allowed to be shared if its address is constant or is a constant plus one of the special registers. */ if (CONSTANT_ADDRESS_P (XEXP (x, 0))) return x; if (GET_CODE (XEXP (x, 0)) == PLUS && (XEXP (XEXP (x, 0), 0) == frame_pointer_rtx || XEXP (XEXP (x, 0), 0) == arg_pointer_rtx) && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1))) { /* This MEM can appear in more than one place, but its address better not be shared with anything else. */ if (! x->used) XEXP (x, 0) = copy_rtx_if_shared (XEXP (x, 0)); x->used = 1; return x; } if (XEXP (x, 0) == frame_pointer_rtx || XEXP (x, 0) == arg_pointer_rtx) return x; } /* This rtx may not be shared. If it has already been seen, replace it with a copy of itself. */ if (x->used) { register rtx copy; unshare_copies++; copy = rtx_alloc (code); bcopy (x, copy, (sizeof (*copy) - sizeof (copy->fld) + sizeof (copy->fld[0]) * GET_RTX_LENGTH (code))); x = copy; copied = 1; } x->used = 1; /* Now scan the subexpressions recursively. We can store any replaced subexpressions directly into X since we know X is not shared! Any vectors in X must be copied if X was copied. */ format_ptr = GET_RTX_FORMAT (code); for (i = 0; i < GET_RTX_LENGTH (code); i++) { switch (*format_ptr++) { case 'e': XEXP (x, i) = copy_rtx_if_shared (XEXP (x, i)); break; case 'E': if (XVEC (x, i) != NULL) { register int j; if (copied) XVEC (x, i) = gen_rtvec_v (XVECLEN (x, i), &XVECEXP (x, i, 0)); for (j = 0; j < XVECLEN (x, i); j++) XVECEXP (x, i, j) = copy_rtx_if_shared (XVECEXP (x, i, j)); } break; } } return x;}/* Copy X if necessary so that it won't be altered by changes in OTHER. Return X or the rtx for the pseudo reg the value of X was copied into. OTHER must be valid as a SET_DEST. */rtxmake_safe_from (x, other) rtx x, other;{ while (1) switch (GET_CODE (other)) { case SUBREG: other = SUBREG_REG (other); break; case STRICT_LOW_PART: case SIGN_EXTEND: case ZERO_EXTEND: other = XEXP (other, 0); break; default: goto done; } done: if ((GET_CODE (other) == MEM && ! CONSTANT_P (x) && GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != REG && GET_CODE (x) != SUBREG) || (GET_CODE (other) == REG && (REGNO (other) < FIRST_PSEUDO_REGISTER || reg_mentioned_p (other, x)))) { rtx temp = gen_reg_rtx (GET_MODE (x)); emit_move_insn (temp, x); return temp; } return x;}/* Emission of insns (adding them to the doubly-linked list). *//* Return the first insn of the current sequence or current function. */rtxget_insns (){ return first_insn;}/* Return the last insn emitted in current sequence or current function. */rtxget_last_insn (){ return last_insn;}/* Specify a new insn as the last in the chain. */voidset_last_insn (insn) rtx insn;{ if (NEXT_INSN (insn) != 0) abort (); last_insn = insn;}/* Return a number larger than any instruction's uid in this function. */intget_max_uid (){ return cur_insn_uid;}rtxnext_insn (insn) rtx insn;{ if (insn) return NEXT_INSN (insn); return 0;}rtxprevious_insn (insn) rtx insn;{ if (insn) return PREV_INSN (insn); return 0;}/* Make and return an INSN rtx, initializing all its slots. Store PATTERN in the pattern slots. PAT_FORMALS is an idea that never really went anywhere. */static rtxmake_insn_raw (pattern, pat_formals) rtx pattern; rtvec pat_formals;{ register rtx insn; insn = rtx_alloc(INSN); INSN_UID(insn) = cur_insn_uid++; PATTERN (insn) = pattern; INSN_CODE (insn) = -1; LOG_LINKS(insn) = NULL; REG_NOTES(insn) = NULL; return insn;}/* Like `make_insn' but make a JUMP_INSN instead of an insn. */static rtxmake_jump_insn_raw (pattern, pat_formals) rtx pattern; rtvec pat_formals;{ register rtx insn; insn = rtx_alloc(JUMP_INSN); INSN_UID(insn) = cur_insn_uid++; PATTERN (insn) = pattern; INSN_CODE (insn) = -1; LOG_LINKS(insn) = NULL; REG_NOTES(insn) = NULL; JUMP_LABEL(insn) = NULL; return insn;}/* Add INSN to the end of the doubly-linked list. INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE. */static voidadd_insn (insn) register rtx insn;{ PREV_INSN (insn) = last_insn; NEXT_INSN (insn) = 0; if (NULL != last_insn) NEXT_INSN (last_insn) = insn; if (NULL == first_insn) first_insn = insn; last_insn = insn;}/* Add INSN, an rtx of code INSN, into the doubly-linked list after insn AFTER. */static voidadd_insn_after (insn, after) rtx insn, after;{ NEXT_INSN (insn) = NEXT_INSN (after); PREV_INSN (insn) = after; if (NEXT_INSN (insn)) PREV_INSN (NEXT_INSN (insn)) = insn; else if (last_insn == after) last_insn = insn; else { rtx stack = sequence_stack; /* Scan all pending sequences too. */ for (; stack; stack = XEXP (XEXP (stack, 1), 1)) if (after == XEXP (XEXP (stack, 1), 0)) XEXP (XEXP (stack, 1), 0) = insn; } NEXT_INSN (after) = insn;}/* Delete all insns made since FROM. FROM becomes the new last instruction. */voiddelete_insns_since (from) rtx from;{ if (from == 0) first_insn = 0; else NEXT_INSN (from) = 0; last_insn = from;}/* Move a consecutive bunch of insns to a different place in the chain. The insns to be moved are those between FROM and TO. They are moved to a new position after the insn AFTER. */voidreorder_insns (from, to, after) rtx from, to, after;{ /* Splice this bunch out of where it is now. */ if (PREV_INSN (from)) NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to); if (NEXT_INSN (to)) PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from); if (last_insn == to) last_insn = PREV_INSN (from); if (first_insn == from) first_insn = NEXT_INSN (to); /* Make the new neighbors point to it and it to them. */ if (NEXT_INSN (after)) { PREV_INSN (NEXT_INSN (after)) = to; NEXT_INSN (to) = NEXT_INSN (after); } PREV_INSN (from) = after; NEXT_INSN (after) = from; if (after == last_insn) last_insn = to;}/* Emit an insn of given code and pattern at a specified place within the doubly-linked list. *//* Make an instruction with body PATTERN and output it before the instruction BEFORE. */rtxemit_insn_before (pattern, before) register rtx pattern, before;{ register rtx insn; if (GET_CODE (pattern) == SEQUENCE) { register int i; /* For an empty sequence, emit nothing. */ if (XVEC (pattern, 0)) for (i = 0; i < XVECLEN (pattern, 0); i++) add_insn_after (XVECEXP (pattern, 0, i), PREV_INSN (before)); return PREV_INSN (before); } insn = make_insn_raw (pattern, 0); PREV_INSN (insn) = PREV_INSN (before); NEXT_INSN (insn) = before; if (PREV_INSN (insn)) NEXT_INSN (PREV_INSN (insn)) = insn; else first_insn = insn; PREV_INSN (before) = insn; return insn;}/* Make an instruction with body PATTERN and code JUMP_INSN and output it before the instruction BEFORE. */rtxemit_jump_insn_before (pattern, before) register rtx pattern, before;{ register rtx insn = make_jump_insn_raw (pattern, 0); PREV_INSN (insn) = PREV_INSN (before); NEXT_INSN (insn) = before; if (PREV_INSN (insn)) NEXT_INSN (PREV_INSN (insn)) = insn; else first_insn = insn; PREV_INSN (before) = insn; return insn;}/* Make an instruction with body PATTERN and code CALL_INSN and output it before the instruction BEFORE. */rtxemit_call_insn_before (pattern, before) register rtx pattern, before;{ rtx insn = emit_insn_before (pattern, before); PUT_CODE (insn, CALL_INSN); return insn;}/* Make an insn of code INSN with body PATTERN and output it after the insn AFTER. */rtxemit_insn_after (pattern, after) register rtx pattern, after;{ if (GET_CODE (pattern) == SEQUENCE) { register int i; /* For an empty sequence, emit nothing. */ if (XVEC (pattern, 0)) for (i = 0; i < XVECLEN (pattern, 0); i++) { add_insn_after (XVECEXP (pattern, 0, i), after); after = NEXT_INSN (after); } return after; } else { register rtx insn = make_insn_raw (pattern, 0); add_insn_after (insn, after); return insn; }}/* Make an insn of code JUMP_INSN with body PATTERN and output it after the insn AFTER. */rtxemit_jump_insn_after (pattern, after) register rtx pattern, after;{ register rtx insn = make_jump_insn_raw (pattern, 0); add_insn_after (insn, after); return insn;}/* Make an insn of code BARRIER and output it after the insn AFTER. */rtxemit_barrier_after (after) register rtx after;{ register rtx insn = rtx_alloc (BARRIER); INSN_UID (insn) = cur_insn_uid++; add_insn_after (insn, after); return insn;}/* Emit the label LABEL after the insn AFTER. */voidemit_label_after (label, after) rtx label, after;{ /* This can be called twice for the same label as a result of the confusion that follows a syntax error! So make it harmless. */ if (INSN_UID (label) == 0) { INSN_UID (label) = cur_insn_uid++; add_insn_after (label, after); }}/* Emit a note of subtype SUBTYPE after the insn AFTER. */voidemit_note_after (subtype, after) int subtype; rtx after;{ register rtx note = rtx_alloc (NOTE); INSN_UID (note) = cur_insn_uid++; XSTR (note, 3) = 0; XINT (note, 4) = subtype; add_insn_after (note, after);}/* Make an insn of code INSN with pattern PATTERN and add it to the end of the doubly-linked list. If PATTERN is a SEQUENCE, take the elements of it and emit an insn for each element. Returns the last insn emitted. */rtxemit_insn (pattern) rtx pattern;{ rtx insn; if (GET_CODE (pattern) == SEQUENCE) { register int i; /* For an empty sequence, emit nothing. */ if (XVEC (pattern, 0)) for (i = 0; i < XVECLEN (pattern, 0); i++) add_insn (insn = XVECEXP (pattern, 0, i)); } else {
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -